Wednesday, May 21, 2014

Why is my Java process is taking more memory than the max heap (Xmx) size


Some times you can see your java process is consuming more memory than you specified in your application (Startup scripts, Xmx). This blog entry will give a short description of why the jvm process is consuming more memory.

Use the below command to get the your application java process id.

Example:
ps -ef | grep "java" | awk '{print $2}'
8096

$ ps aux | grep 8096
oracle 8096  5.5 22.4 6891548 5531984 ?     Sl   May10 573:10 /u01/app/oracle/product/fmw/jrockit-jdk1.6.0_37-R28.2.5-4.1.0/bin/java -jrockit -Xms4096m -Xmx4096m -Dweblogic.log.RedirectStdoutToServerLogEnabled=true -server -XX:+UseStringCache -Djrockit.oomdiagnostics=true -Dweblogic.Name=apptest_soa1 -Djava.security.policy=/u01/app/oracle/product/fmw/wlserver_10.3/server/lib/weblogic.polic

From the above stats, the actual size of physical memory (RAM) used by the java process (pid: 8096) (known as resident memory of the process) is 5531984KB (~5.27GB) even though the max heap size of the java process is 4GB.


Even by using top command, you will get the similar statistics.

$ top -p 8096
top - 15:16:28 up 234 days, 19:20,  2 users,  load average: 0.00, 0.00, 0.00
Tasks:   1 total,   0 running,   1 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.0%us,  0.2%sy,  0.0%ni, 99.7%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  24638424k total, 13084140k used, 11554284k free,   496232k buffers
Swap: 12578852k total,        0k used, 12578852k free,  5588616k cached

PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                                                          
8096 oracle  20   0 6730m 5.3g  16m S  1.7 22.5 572:25.40 java      

RES  which stand for Resident Set Size is the portion of a process's memory that is held in RAM.
VSZ which stand for Virtual Set Size is the portion of a process's virtual memory. And also you can observe that the memory utilization (RES) is 5.3GB which is more than your max heap 4GB.


The -Xmx switch which you have used during your start-up scripts is limiting the memory consumed by your application heap. Besides heap memory, you java application process uses other part of the memory. You are already aware of different Memory Spaces available as part of the Java Process.

Java Process Memory= Max Heap Memory + Max PermGeneration  Memory + Native Memory

Total memory utilization of the JVM process consist of more things than just the Java heap. The jvm process uses more memory for various reasons. Below are few examples:
  • JNI Code
  • JIT Optimization
  • Loaded libraries (including jar and class files)
  • Thread Stacks
  • Garbage Collection etc.,