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

5

57

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

Globular answered 22/1, 2013 at 17:42 Comment(0)
S
69

You can use jstat, like :

 jstat -gc pid

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

Sommersommers answered 22/1, 2013 at 17:44 Comment(3)
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 usedGlobular
so i think OU is the key column, with OC showing the max that was allocatedGlobular
@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.Logogriph
T
22

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.

Talishatalisman answered 19/1, 2017 at 17:44 Comment(0)
B
14

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 ]

Botulism answered 19/10, 2018 at 17:19 Comment(7)
Why are you summing YGCT too? It's a timeChristopher
regarding your question: ps shows the allocated system memory and not the heap usage. Thus, java might allocate memory, which is unused.Melodious
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 -mMelodious
@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! =DBotulism
@Christopher Adjusted! Thanks! =DBotulism
@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.Melodious
@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! =DBotulism
E
9

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.

Encompass answered 22/1, 2013 at 17:51 Comment(0)
C
5

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

jcmd < pid > GC.heap_info
Canicular answered 4/3, 2021 at 12:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.