Stavo eseguendo test di carico su un server tomcat. Il server ha memoria fisica 10G e spazio di scambio 2G. La dimensione heap (xms e xmx) era impostata su 3G prima e il server funzionava correttamente. Dato che ho ancora visto molti ricordi liberi e le prestazioni non erano buone, ho aumentato le dimensioni dell'heap a 7G e ho eseguito di nuovo il test di caricamento. Questa volta ho osservato che la memoria fisica è stata consumata molto rapidamente e il sistema ha iniziato a consumare spazio di swap. Successivamente, tomcat si è bloccato dopo aver esaurito lo spazio di swap. Ho incluso -XX:+HeapDumpOnOutOfMemoryError
all'avvio di tomcat, ma non ho ricevuto alcun dump dell'heap. Quando ho controllato /var/log/messages
, ho visto kernel: Out of memory: Kill process 2259 (java) score 634 or sacrifice child
.Processo di tomcat ucciso dal kernel Linux dopo aver esaurito lo spazio di swap; non ottieni alcun errore JVM OutOfMemory
Per fornire maggiori informazioni, ecco quello che ho visto da Linux top
comando quando dimensione heap impostato su 3G e 7G
XMS & xmx = 3G (che ha lavorato bene):
Prima Tomcat di partenza:
Mem: 10129972k total, 1135388k used, 8994584k free, 19832k buffers Swap: 2097144k total, 0k used, 2097144k free, 56008k cached
Dopo Tomcat partenza:
Mem: 10129972k total, 3468208k used, 6661764k free, 21528k buffers Swap: 2097144k total, 0k used, 2097144k free, 143428k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 2257 tomcat 20 0 5991m 1.9g 19m S 352.9 19.2 3:09.64 java
Dopo aver avviato carico per 10 min:
Mem: 10129972k total, 6354756k used, 3775216k free, 21960k buffers Swap: 2097144k total, 0k used, 2097144k free, 144016k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 2257 tomcat 20 0 6549m 3.3g 10m S 332.1 34.6 16:46.87 java
xms & xmx = 7G (che ha causato arresto tomcat):
Prima di avviare tomcat:
Mem: 10129972k total, 1270348k used, 8859624k free, 98504k buffers Swap: 2097144k total, 0k used, 2097144k free, 74656k cached
Dopo l'avvio Tomcat:
Mem: 10129972k total, 6415932k used, 3714040k free, 98816k buffers Swap: 2097144k total, 0k used, 2097144k free, 144008k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 2310 tomcat 20 0 9.9g 3.5g 10m S 0.3 36.1 3:01.66 java
Dopo l'avvio di carico per 10 minuti (a destra prima di Tomcat è stato ucciso):
Mem: 10129972k total, 9960256k used, 169716k free, 164k buffers Swap: 2097144k total, 2095056k used, 2088k free, 3284k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 2310 tomcat 20 0 10.4g 5.3g 776 S 9.8 54.6 14:42.56 java
Java e JVM Versione:
Java(TM) SE Runtime Environment (build 1.7.0_21-b11)
Java HotSpot(TM) 64-Bit Server VM (build 23.21-b01, mixed mode)
Tomcat Versione:
6.0.36
Linux Server:
Red Hat Enterprise Linux Server release 6.4 (Santiago)
Quindi le mie domande sono:
- Perché questo problema accadere? Quando JVM esaurisce la memoria, perché non viene generato alcun errore OutOfMemoryError? E perché va dritto all'utilizzo dello swap?
- Perché
top
RES
indica che java sta usando la memoria 5.3G, c'è molta più memoria consumata?
Ho indagato e cercato per un po ', ancora non riesco a trovare la causa principale di questo problema. Molte grazie!
Una domanda migliore è perché Tomcat utilizza così tanta memoria? Puoi ancora ottenere un heap dump inviando il processo SIGQUIT (kill -3) o con 'jmap'. Eclipse MAT è probabilmente il modo più semplice per analizzare il dump se la maggior parte della memoria proviene da un unico punto. – AngerClown
grazie! questa è una domanda migliore. Darò sicuramente un'occhiata alla discarica dell'heap. Ma sembra che ci sia anche un sacco di memoria inutilizzata. C'è un modo per controllarli? – baggiowen
Non sono sicuro che possa essere d'aiuto, ma [VMMap] (http://technet.microsoft.com/en-us/sysinternals/dd535533.aspx) può mostrare l'utilizzo della memoria nativa di JVM. Puoi prima controllare le connessioni aperte con 'netstat' - la causa più probabile di una perdita con l'utilizzo di mem nativo sono i thread del contenitore web. – AngerClown