How to check heap usage of a running JVM from the command line?

122,029

Solution 1

You can use jstat, like :

 jstat -gc pid

Full docs here : http://docs.oracle.com/javase/7/docs/technotes/tools/share/jstat.html

Solution 2

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.

Solution 3

All procedure at once. Based on @Till Schäfer answer.

In KB...

jstat -gc $(ps axf | egrep -i "*/bin/java *" | egrep -v grep | awk '{print $1}') | tail -n 1 | awk '{split($0,a," "); sum=(a[3]+a[4]+a[6]+a[8]+a[10]); printf("%.2f KB\n",sum)}'

In MB...

jstat -gc $(ps axf | egrep -i "*/bin/java *" | egrep -v grep | awk '{print $1}') | tail -n 1 | awk '{split($0,a," "); sum=(a[3]+a[4]+a[6]+a[8]+a[10])/1024; printf("%.2f MB\n",sum)}'

"Awk sum" reference:

 a[1] - S0C
 a[2] - S1C
 a[3] - S0U
 a[4] - S1U
 a[5] - EC
 a[6] - EU
 a[7] - OC
 a[8] - OU
 a[9] - PC
a[10] - PU
a[11] - YGC
a[12] - YGCT
a[13] - FGC
a[14] - FGCT
a[15] - GCT

Used for "Awk sum":

a[3] -- (S0U) Survivor space 0 utilization (KB).
a[4] -- (S1U) Survivor space 1 utilization (KB).
a[6] -- (EU) Eden space utilization (KB).
a[8] -- (OU) Old space utilization (KB).
a[10] - (PU) Permanent space utilization (KB).

[Ref.: https://docs.oracle.com/javase/7/docs/technotes/tools/share/jstat.html ]

Thanks!

NOTE: Works to OpenJDK!

FURTHER QUESTION: Wrong information?

If you check memory usage with the ps command, you will see that the java process consumes much more...

ps -eo size,pid,user,command --sort -size | egrep -i "*/bin/java *" | egrep -v grep | awk '{ hr=$1/1024 ; printf("%.2f MB ",hr) } { for ( x=4 ; x<=NF ; x++ ) { printf("%s ",$x) } print "" }' | cut -d "" -f2 | cut -d "-" -f1

UPDATE (2021-02-16):

According to the reference below (and @Till Schäfer comment) "ps can show total reserved memory from OS" (adapted) and "jstat can show used space of heap and stack" (adapted). So, we see a difference between what is pointed out by the ps command and the jstat command.

According to our understanding, the most "realistic" information would be the ps output since we will have an effective response of how much of the system's memory is compromised. The command jstat serves for a more detailed analysis regarding the java performance in the consumption of reserved memory from OS.

[Ref.: http://www.openkb.info/2014/06/how-to-check-java-memory-usage.html ]

Solution 4

If you start execution with gc logging turned on you get the info on file. Otherwise 'jmap -heap ' will give you what you want. See the jmap doc page for more.

Please note that 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.

Solution 5

If you are using JDK 8 and above , use jcmd:

jcmd < pid > GC.heap_info

Share:
122,029

Related videos on Youtube

Paul Taylor
Author by

Paul Taylor

Runs Albunack providing awesome artist discographies and the Jaikoz and SongKong Music Tagger applications. Main skills:Java and Databases. Also, photographer concentrating on the less obvious in South-West England, photographs can be seen at Secret Dorset Photo

Updated on March 05, 2021

Comments

  • Paul Taylor
    Paul Taylor about 3 years

    Can I check heap usage of a running JVM from the commandline, I mean the actual usage rather than the max amount allocated with Xmx.

    I need it to be commandline because I don't have access to a windowing environment, and I want script based on the value , the application is running in Jetty Application server

  • Paul Taylor
    Paul Taylor over 11 years
    Thankyou looks like what I want, might take a while to understand all the options though, I was basically looking for how much of the heap is used
  • Paul Taylor
    Paul Taylor over 11 years
    so i think OU is the key column, with OC showing the max that was allocated
  • pacoverflow
    pacoverflow over 9 years
    @PaulTaylor You want the EU and OU columns - adding them up gives you the amount of the heap that is used. Adding up the EC and OC columns gives you the amount allocated for the heap.
  • Kalpesh Soni
    Kalpesh Soni almost 7 years
    how do you do this if jvm is running as one linux user and you login as another?
  • Gamby
    Gamby over 4 years
    Why are you summing YGCT too? It's a time
  • Till Schäfer
    Till Schäfer over 4 years
    regarding your question: ps shows the allocated system memory and not the heap usage. Thus, java might allocate memory, which is unused.
  • Till Schäfer
    Till Schäfer over 4 years
    the java pid retreaval will not work for multiple java processes. Its better to do somthink like for pid in $(ps -o pid= -C java); do [...] done or to use jps -m
  • Eduardo Lucio
    Eduardo Lucio over 3 years
    @TillSchäfer I didn't really understand what you meant by $(ps -o pid= -C java); do [...] done... Could you show us a complete example of what you wanted to explain? So I can further enrich my answer. Thanks! =D
  • Eduardo Lucio
    Eduardo Lucio over 3 years
    @Gamby Adjusted! Thanks! =D
  • Till Schäfer
    Till Schäfer about 3 years
    @EduardoLucio your statement $(ps axf | egrep -i "*/bin/java *" | egrep -v grep | awk '{print $1}') is functionally equivalent to the much shorter $(ps -o pid= -C java). The second one does only rely on ps (not egrep, awk), and does not rely on fixed paths of the java installation. Furthermore, jstat only accepts a singe vm pid. Thus, your command will fail for more than a single java instance. This is the reason you should loop over the pid of all running vms and execute the jstat command for each pid.
  • Eduardo Lucio
    Eduardo Lucio about 3 years
    @TillSchäfer I don't know how to adapt this command jstat -gc $(ps axf | egrep -i "*/bin/java *" | egrep -v grep | awk '{print $1}') | tail -n 1 | awk '{split($0,a," "); sum=(a[3]+a[4]+a[6]+a[8]+a[10])/1024; printf("%.2f MB\n",sum)}' to use this excerpt for pid in $(ps -o pid= -C java); do [...] done that you showed us... Thanks and sorry about that! =D