Understanding Java Memory Usage


http://stackoverflow.com/questions/12797560/command-line-tool-to-find-java-heap-size-and-memory-used-linux - done reading

How can we determine the memory usage of a Java process?

Using top command is the simplest way to check memory usage of the program. RES column shows the real physical memory that is occupied by a process. For my case, I had a 10g file read in java and each time I got outOfMemory exception. This happened when the value in the RES column reached to the value set in -Xmx option. Then by increasing the memory using -Xmx option everything went fine.

In Linux, you can use:

ps aux | grep java
ps -ef | grep java

and look for -Xms, -Xmx to find out the initial and maximum heap size specified. However, if -Xms or -Xmx is absent for the Java process you are interested in, it means your Java process is using the default heap sizes. You can use the following command to find out the default sizes.

java -XX:+PrintFlagsFinal -version | grep HeapSize
/path/to/jdk1.8.0_102/bin/java -XX:+PrintFlagsFinal -version | grep HeapSize

and look for InitialHeapSize and MaxHeapSize, which is in bytes.

Each Java process has a pid, which you first need to find with the jps command. Once you have the pid, you can use jstat -gc [insert-pid-here] to find statistics of the behavior of the garbage collected heap.

  • jstat -gccapacity [insert-pid-here] will present information about memory pool generation and space capabilities.
  • jstat -gcutil [insert-pid-here] will present the utilization of each generation as a percentage of its capacity. Useful to get an at a glance view of usage.

"jstat -gcutil <pid> 250 N" was very useful to take N samples with 250ms intervals and display the output as percentages for the corresponding spaces.

awk 'print {$3+$4+$6+$8}' can print summarized usage on Java 8's jstat columns.

java -XX:+PrintFlagsFinal -version | grep HeapSize (works amazon ami on ec2 as well. This doesn't answer the question, which specifically asks how to check heap usage of a process. The command here lists JVM defaults across all processes. Will this print the Heap Sizes in bytes.)

Without using JMX, which is what most tools use, all you can do is use:

jps -lvm

and infer that the settings will be from the command line options. You can't get dynamic information without JMX by default but you could write your own service to do this.

I prefer to use VisualVM rather than JConsole.

// Ubuntu and RedHat
java -XX:+PrintFlagsFinal -version | grep -iE 'HeapSize|PermSize|ThreadStackSize'

// Windows:
java -XX:+PrintFlagsFinal -version | findstr /i "HeapSize PermSize ThreadStackSize"

// Mac:
java -XX:+PrintFlagsFinal -version | grep -iE 'heapsize|permsize|threadstacksize'

The output of the above commands are in bytes.  To find the size in MB divide the value with (1024*1024).
ps -orss= -p $(/sbin/pidof java)
ps -opid,rss,vsz -p $(/sbin/pidof java)
jstat -gc pid

jmap should not be used in a production environment unless absolutely needed as the tool halts the application to be able to determine actual heap usage. Usually this is not desired in a production environment.

For Java 8 you can use the following command line to get the heap space utilization in kB:

jstat -gc <PID> | tail -n 1 | awk '{split($0,a," "); sum=a[3]+a[4]+a[6]+a[8]; print sum}'

The command basically sums up:

  • S0U: Survivor space 0 utilization (kB).
  • S1U: Survivor space 1 utilization (kB).
  • EU: Eden space utilization (kB).
  • OU: Old space utilization (kB).

You may also want to include the metaspace and the compressed class space utilization. In this case you have to add a[10] and a[12] to the awk sum.

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License