我能否通过命令行检查运行中JVM的堆使用情况,我指的是实际使用情况而不是使用Xmx分配的最大量。
我需要使用命令行,因为我没有访问窗口环境,并且我想要根据此值编写脚本,该应用程序正在Jetty应用服务器上运行。
我能否通过命令行检查运行中JVM的堆使用情况,我指的是实际使用情况而不是使用Xmx分配的最大量。
我需要使用命令行,因为我没有访问窗口环境,并且我想要根据此值编写脚本,该应用程序正在Jetty应用服务器上运行。
您可以使用jstat,例如:
jstat -gc pid
完整文档在此处: http://docs.oracle.com/javase/7/docs/technotes/tools/share/jstat.html
对于Java 8,您可以使用以下命令行以kB为单位获取堆空间利用率:
jstat -gc <PID> | tail -n 1 | awk '{split($0,a," "); sum=a[3]+a[4]+a[6]+a[8]; print sum}'
这个命令基本上总结了:
你可能还想包括元空间和压缩类空间的利用情况。在这种情况下,你需要将 a[10] 和 a[12] 添加到 awk 总和中。
一次性地完成所有程序。基于@Till Schäfer的回答。
以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)}'
在 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"参考:
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
用于“Awk求和”:
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).
[参考资料:https://docs.oracle.com/javase/7/docs/technotes/tools/share/jstat.html]
谢谢!
注意:适用于OpenJDK!
进一步问题:信息错误?
如果您使用ps
命令检查内存使用情况,您会发现Java 进程消耗了更多的内存...
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
更新(2021-02-16):
根据以下参考资料(和@Till Schäfer的评论),“ps 可以显示从操作系统保留的内存总量”(经过适应),“jstat 可以显示堆和栈使用空间”(经过适应)。因此,我们看到了 ps
命令和 jstat
命令所指出的差异。
根据我们的理解,最 “真实” 的信息应该是 ps
输出,因为我们将有效地了解系统的内存储备量。而 jstat
命令则用于更详细的分析,关于 Java 在从操作系统中消耗保留内存方面的性能。
[参考资料:http://www.openkb.info/2014/06/how-to-check-java-memory-usage.html]
for pid in $(ps -o pid= -C java); do [...] done
或者使用jps -m
的方法。 - Till Schäfer$(ps -o pid= -C java); do [...] done
,能否给我们展示一个完整的例子来解释一下呢?这样我就可以进一步丰富我的回答了。谢谢!=D - Eduardo Lucio$(ps axf | egrep -i "*/bin/java *" | egrep -v grep | awk '{print $1}')
在功能上等同于更短的语句 $(ps -o pid= -C java)
。第二个语句仅依赖于 ps(而不是 egrep、awk),并且不依赖于 Java 安装的固定路径。此外,jstat 仅接受单个 vm pid。因此,如果有多个 Java 实例,则您的命令将失败。这就是为什么您应该循环遍历所有运行的 vms 的 pid,并为每个 pid 执行 jstat 命令的原因。 - Till Schäfer