How to check heap usage of a running JVM from the command line?
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
Related videos on Youtube
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, 2021Comments
-
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 over 11 yearsThankyou 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 over 11 yearsso i think OU is the key column, with OC showing the max that was allocated
-
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 almost 7 yearshow do you do this if jvm is running as one linux user and you login as another?
-
Gamby over 4 yearsWhy are you summing YGCT too? It's a time
-
Till Schäfer over 4 yearsregarding your question: ps shows the allocated system memory and not the heap usage. Thus, java might allocate memory, which is unused.
-
Till Schäfer over 4 yearsthe 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 usejps -m
-
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 over 3 years@Gamby Adjusted! Thanks! =D
-
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 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 excerptfor pid in $(ps -o pid= -C java); do [...] done
that you showed us... Thanks and sorry about that! =D