I’m having a weird issue with a java process which is consuming a lot of resources on a linux VM. The output of top for the process is the below :
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1182 blabla 20 0 25.5g 21g 45m S 382.9 33.9 139840:17 java
So this shows that the process is actually consuming 21G of physical memory ?
When checking the process in more detail I can see it was started with -Xmx4G . Is there any logical explanation for the 21G shown on “top” ? (Ignore the first -Xmx from ps output below)
blabla@dtraflocorh391:~ $ ps aux | grep 1182 blabla 1182 249 33.8 26716716 22363868 ? Sl Feb13 139847:01 java -Xms32M -Xmx128M -showversion -Djavax.xml.stream.XMLEventFactory=com.ctc.wstx.stax.WstxEventFactory -Djavax.xml.stream.XMLInputFactory=com.ctc.wstx.stax.WstxInputFactory -Djavax.xml.stream.XMLOutputFactory=com.ctc.wstx.stax.WstxOutputFactory -Xms256M -Xmx4G -verbose:gc -XX:+PrintGCTimeStamps ... ... ...
… …
Advertisement
Answer
-Xmx
controls the maximum heap size – essentially where stuff created with the new
keyword is stored.
Java has other pools of memory – for the execution stack, for caching JIT compiled code, for storing loaded classes and dynamically created classes, for memory-mapped files, the heap space used by native code (JNI, or just Hotspot itself): see How is the java memory pool divided?
JConsole is one tool you can use to see what your Java program is using memory for. Once JConsole has told you which area is big/full, you can start to reason about why it’s got like that.
For example, I once had a program that loaded a new Jackson object mapper for every parse — and this version of Jackson had a bug whereby it left dynamic classes in non-heap memory which never got GCd. Your problem might be this, or it might be something completely different. JConsole will tell.