用于查找Java堆大小的命令行工具

2025/04/26

1. 概述

在本快速教程中,我们将熟悉几种获取正在运行的Java应用程序的堆大小的不同方法。

2. jcmd

要查找正在运行的Java应用程序的堆和元空间相关信息,我们可以使用jcmd命令行实用程序

jcmd  GC.heap_info

首先,让我们使用jps命令找到特定Java应用程序的进程ID:

$ jps -l
73170 org.jetbrains.idea.maven.server.RemoteMavenServer36
4309  quarkus.jar
12070 sun.tools.jps.Jps

如上所示,我们的Quarkus应用程序的进程ID是4309,现在我们有了进程ID,让我们看看堆信息:

$ jcmd 4309 GC.heap_info
4309:
 garbage-first heap   total 206848K, used 43061K
  region size 1024K, 43 young (44032K), 3 survivors (3072K)
 Metaspace       used 12983K, capacity 13724K, committed 13824K, reserved 1060864K
  class space    used 1599K, capacity 1740K, committed 1792K, reserved 1048576K

此应用程序使用G1 GC算法

  • 第一行报告当前堆大小为202MB(206848K),并且已使用42MB(43061K)。
  • G1区域为1MB,其中43个区域标记为年轻区域,3个区域标记为幸存者空间。
  • 元空间的当前容量约为13.5MB(13724K),其中,大约有12.5MB(12983K)已被使用。此外,我们最多可以拥有1GB的元空间(1048576K)。此外,Java虚拟机保证可以使用13842KB的内存,这也称为已提交内存。
  • 最后一行显示了有多少元空间用于存储类信息。

此输出可能会根据GC算法而变化,例如,如果我们通过“-XX:+UnlockExperimentalVMOptions-XX:+UseZGC”使用ZGC运行相同的Quarkus应用程序:

ZHeap           used 28M, capacity 200M, max capacity 1024M
Metaspace       used 21031K, capacity 21241K, committed 21504K, reserved 22528K

如上所示,我们使用了28MB的堆内存和大约20MB的元空间。截至撰写本文时,Intellij IDEA仍在使用CMS GC,其堆内存信息如下:

par new generation   total 613440K, used 114299K
  eden space 545344K,  18% used
  from space 68096K,  16% used
  to   space 68096K,   0% used
 concurrent mark-sweep generation total 1415616K, used 213479K
 Metaspace       used 423107K, capacity 439976K, committed 440416K, reserved 1429504K
  class space    used 55889K, capacity 62488K, committed 62616K, reserved 1048576K

我们可以在堆配置中发现CMS GC的经典代际特性。

3. jstat

除了jcmd之外,我们还可以使用jstat从正在运行的应用程序中获取相同的信息,例如,我们可以使用jstat-gc查看堆统计信息:

$ jstat -gc 4309
S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     
0.0    0.0    0.0    0.0   129024.0  5120.0   75776.0    10134.6   20864.0
MU      CCSC   CCSU     YGC     YGCT    FGC    FGCT     CGC    CGCT     GCTGCT
19946.2 2688.0 2355.0    2      0.007    1      0.020    0     0.000     0.027

每列代表特定内存区域的内存容量或利用率:

  • S0C:第一个幸存者空间的容量
  • S1C:第二个幸存者空间的容量
  • S0U:第一个幸存者的已用空间
  • S1U:第二个幸存者的已用空间
  • EC:Eden空间容量
  • EU:Eden已使用空间
  • OC:老年代容量
  • OU:老年代已用空间
  • MC:元空间容量
  • MU:元空间已用空间
  • CCSC:压缩类空间容量
  • CCSU:压缩类空间已用空间
  • YGC:Minor GC的数量
  • YGCT:Minor GC所花费的时间
  • FGC:Full GC的数量
  • FGCT:Full GC所花费的时间
  • CGC:Concurrent GC的数量
  • CGCT:Concurrent GC所花费的时间
  • GCT:所有GC所花费的时间

jstat还有其他与内存相关的选项,例如:

  • -gccapacity报告不同内存区域的不同容量
  • -gcutil仅显示每个区域的利用率百分比
  • -gccause与-gcutil相同,但添加了上次GC的原因以及可能的当前GC事件

4. 命令行参数

如果我们使用堆配置选项(例如-Xms和-Xmx)运行Java应用程序,那么还有一些其他技巧可以找到指定的值。

例如,jps报告这些值的方式如下:

$ jps -lv
4309 quarkus.jar -Xms200m -Xmx1g

使用这种方法,我们只能找到这些静态值,因此,我们无法了解当前已提交的内存

除了jps之外,其他一些工具也会报告同样的情况,例如,“jcmd <pid> VM.command_line”也会报告以下详细信息:

$ jcmd 4309 VM.command_line
4309:
VM Arguments:
jvm_args: -Xms200m -Xmx1g
java_command: quarkus.jar
java_class_path (initial): quarkus.jar
Launcher Type: SUN_STANDARD

另外,在大多数基于Unix的系统上,我们可以使用procps包中的ps

$ ps -ef | grep quarkus
... java -Xms200m -Xmx1g -jar quarkus.jar

最后,在Linux上,我们可以使用/proc虚拟文件系统及其pid文件:

$ cat /proc/4309/cmdline
java -Xms200m -Xmx1g -jar quarkus.jar

cmdline文件位于以Quarkus pid命名的目录中,包含应用程序的命令行条目。

5. 总结

在本快速教程中,我们看到了几种获取正在运行的Java应用程序的堆大小的不同方法。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章