Come ridurre Sun / Oracle JVM in testa interna?
Domanda
Il problema è specificamente circa Sun Java JVM in esecuzione su Linux x86-64 . Sto cercando di capire perché il Sun JVM prende così tanto della memoria fisica del sistema anche quando ho impostato Heap e non Heap limiti .
Il programma sto correndo è Eclipse 3.7 con molteplici plugins / caratteristiche. Le caratteristiche più utilizzati sono PDT, EGit e Mylyn. Sto iniziando Eclipse con gli interruttori seguente riga di comando:
-nosplash -vmargs -Xincgc -Xms64m -Xmx200m -XX:NewSize=8m -XX:PermSize=80m -XX:MaxPermSize=150m -XX:MaxPermHeapExpansion=10m -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSInitiatingOccupancyOnly -XX:+UseParNewGC -XX:+CMSIncrementalMode -XX:+CMSIncrementalPacing -XX:CMSIncrementalDutyCycleMin=0 -XX:CMSIncrementalDutyCycle=5 -XX:GCTimeRatio=49 -XX:MaxGCPauseMillis=50 -XX:GCPauseIntervalMillis=1000 -XX:+UseCMSCompactAtFullCollection -XX:+CMSClassUnloadingEnabled -XX:+DoEscapeAnalysis -XX:+UseCompressedOops -XX:+AggressiveOpts -Dorg.eclipse.swt.internal.gtk.disablePrinting
Da notare sono soprattutto gli interruttori:
-Xms64m -Xmx200m -XX:NewSize=8m -XX:PermSize=80m -XX:MaxPermSize=150m
Questi switch dovrebbe limitare la JVM Heap ad un massimo di 200 MB e non Heap a 150 MB ( "generazione CMS permanente" e "Codice Cache", come etichettati da JConsole). Logicamente la JVM dovrebbe prendere totale di 350 MB, più l'overhead interna richiesta dalla JVM.
In realtà, la JVM prende 544,6 MB per il mio attuale processo di Eclipse come calcolato da ps_mem.py ( http://www.pixelbeat.org/scripts/ps_mem.py ) che calcola i veri pagine di memoria fisica riservati dal kernel di Linux 2.6+. Questo è interno Sun JVM sovraccarico del 35% o di circa 200MB!
Eventuali suggerimenti su come ridurre questo sovraccarico?
Ecco alcune informazioni aggiuntive:
$ ps auxw
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
me 23440 2.4 14.4 1394144 558440 ? Sl Oct12 210:41 /usr/bin/java ...
E secondo JConsole, il processo ha utilizzato 160 MB di cumulo e 151 MB di non-heap.
Non sto dicendo che non mi posso permettere usando 200MB in più per l'esecuzione di Eclipse, ma se c'è un modo per ridurre questo spreco, preferisco usare quel 200MB per i buffer dei dispositivi di blocco del kernel o cache dei file. Inoltre, ho esperienza simile con altri programmi Java - forse avrei potuto ridurre il sovraccarico per tutti loro con modifiche simili
. Aggiornamento: Dopo la pubblicazione della domanda, ho trovato post precedente a SO:
Perché il Sun JVM continuano a consumare la memoria sempre più RSS, anche quando l'heap, ecc dimensioni sono stabili?
Sembra che dovrei usare pmap
per investigare il problema.
Soluzione
Penso che la ragione per l'elevato consumo di memoria del vostro Eclipse dell'Ambiente è l'uso di SWT. SWT è un nativo libreria grafica di fuori vivente del mucchio di JVM, ed a peggiorare la situazione, l'implementazione su Linux non è davvero ottimizzato.
Io non credo che ci sia davvero la possibilità di ridurre il consumo di memoria del vostro ambiente Eclipse relativo alla memoria al di fuori del mucchio.
Altri suggerimenti
Eclipse è una memoria e CPU hog. In aggiunta alle librerie di classi Java tutta la roba a basso GUI fine è gestita da chiamate di sistema nativi in ??modo da avere una consistente libreria "nativo" JNI per eseguire le chiamate termine livello X bassi collegati al processo.
Eclipse che offrono milioni di utili funzioni e un sacco di aiutanti per accelerare il vostro giorno per giorno le attività di programmazione - ma magra e media non lo è. Qualsiasi riduzione della memoria o le risorse probabilmente porterà ad un rallentamento evidente. Dipende molto da quanto il vostro tempo contro la memoria dei computer.
Se si desidera gvim magra e media e fare sono imbattibili. Se si desidera che il completamento del codice, costruisce automatica ecc si deve aspettare di pagare per questo con risorse aggiuntive.
Se si esegue il seguente programma
public static void main(String... args) throws InterruptedException {
for (int i = 0; i < 60; i++) {
System.out.println("waiting " + i);
Thread.sleep(1000);
}
}
con ps auwx
stampe
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
500 13165 0.0 0.0 596680 13572 pts/2 Sl+ 13:54 0:00 java -Xms64m -Xmx200m -XX:NewSize=8m -XX:PermSize=80m -XX:MaxPermSize=150m -cp . Main
La quantità di memoria utilizzata è di 13,5 MB. Ci circa 200 MB di librerie condivise che conta verso la dimensione VSZ. Il resto può essere acounted cui mucchio max, max perm GEN con un overhead per il filo pile etc.
Il problema non sembra essere con la JVM, ma l'applicazione in esecuzione in esso. Utilizzando ulteriori librerie condivise, diretto alla memoria e file mappati in memoria può aumentare la quantità di memoria utilizzata.
Dato che si possono acquistare 16 GB per circa $ 100, lo sai questo è in realtà un problema?