1. 命令行工具
jps -l:查询已启动的 jar 服务及其对应的 PID。jcmd <PID> VM.command_line:查看 JVM 启动时设置了哪些参数。jcmd <PID> VM.flags:查看 JVM 的自己配置或者jvm自动配置的初始堆内存与最大堆内存
C:\Users\lenovo>jcmd31424VM.flags31424:-XX:CICompilerCount=3-XX:ConcGCThreads=1-XX:G1ConcRefinementThreads=4-XX:G1EagerReclaimRemSetThreshold=32-XX:G1HeapRegionSize=4194304-XX:GCDrainStackTargetSize=64-XX:+HeapDumpOnOutOfMemoryError-XX:HeapDumpPath=E:\ideaworkspace-XX:InitialHeapSize=536870912-XX:+ManagementServer-XX:MarkStackSize=4194304-XX:MaxHeapSize=8564768768-XX:MaxNewSize=5138022400-XX:MinHeapDeltaBytes=4194304-上面是jcmd <PID> VM.flags的输出示例。下面挑出与堆内存、G1 收集器相关的关键参数进行解释:
| 参数 | 含义 |
|---|---|
-XX:InitialHeapSize=536870912 | 初始堆大小,536870912 字节 = 512MB |
-XX:MaxHeapSize=8564768768 | 最大堆大小,8564768768 字节 ≈ 8GB |
-XX:MaxNewSize=5138022400 | 年轻代最大大小,约 4.8GB |
-XX:MinHeapDeltaBytes=4194304 | 堆扩容/缩容的最小增量,4MB |
-XX:G1HeapRegionSize=4194304 | G1 单个 Region 大小,4194304 字节 = 4MB |
-XX:ConcGCThreads=1 | 并发 GC 线程数 |
-XX:G1ConcRefinementThreads=4 | G1 并发 Refinement 线程数 |
-XX:MarkStackSize=4194304 | 标记栈大小,4MB |
-XX:+HeapDumpOnOutOfMemoryError | 发生 OOM 时自动生成堆转储文件 |
-XX:HeapDumpPath=... | 堆转储文件的保存路径 |
-XX:+ManagementServer | 启用 JMX 管理服务器,便于工具远程连接 |
补充说明:
字节数换算:4194304 B = 4MB;536870912 B = 512MB;8564768768 B ≈ 8GB。
VM.flags展示的是当前进程实际生效的参数,既包含用户显式配置,也包含 JVM 自动调整后的值,因此能看到初始堆、最大堆以及 G1 的 Region 大小等关键配置。如果只想确认“最大可以用多少堆、初始堆是多大”,重点看
InitialHeapSize和MaxHeapSize即可。jcmd <PID> GC.heap_info:查看 jar 运行时实际占用的初始堆内存与最大堆内存。
garbage-first heap total 69632K, used 32292K[0x0000000601800000, 0x0000000800000000)region size 4096K,5young(20480K),1survivors(4096K)Metaspace used 34776K, committed 35328K, reserved 1081344K class space used 4868K, committed 5120K, reserved 1048576K上面是jcmd <PID> GC.heap_info的输出示例,当前使用G1 收集器(garbage-first heap)。下面用表格拆解各字段含义:
| 输出片段 | 含义 |
|---|---|
total 69632K | 堆总容量约 68MB |
used 32292K | 堆已使用约 31.5MB |
[0x...1800000, 0x...00000000) | 堆内存的虚拟地址范围 |
region size 4096K | 每个 G1 Region 大小 4MB |
5 young (20480K) | 年轻代 5 个 Region,合计 20MB |
1 survivors (4096K) | Survivor 区 1 个 Region,合计 4MB |
Metaspace(元空间)和class space(类空间)中,used/committed/reserved三列含义相同:
| 列名 | 含义 |
|---|---|
used | 实际已使用内存 |
committed | JVM 已向操作系统提交(申请)的内存 |
reserved | 操作系统为 JVM 保留的虚拟地址空间,只是预留,不直接占用物理内存 |
对应示例中的数值:
| 区域 | used | committed | reserved |
|---|---|---|---|
| Metaspace | 34776K | 35328K | 1081344K |
| class space | 4868K | 5120K | 1048576K |
G1 中,堆被划分为等大的 Region;young表示年轻代 Region(含 Eden 与 Survivor),survivors专指 Survivor 区 Region。结合total、used即可快速了解堆水位和区域分配情况。
jmap:JDK 17 之后,需要改用jhsdb jmap --heap --pid <PID>。不过对于日常快速查看,jcmd的兼容性和开销通常更理想。
2. 实时监控
jstat -gc <PID>:这是一个实时监控工具。输出中EC(Eden 容量)、OC(老年代容量)等字段表示容量(Capacity),EU、OU是对应的已使用量。需要注意的是,它显示的是各个内存池的容量,并不直接等同于“总堆大小”。
3. 图形化工具
jconsole:如果你能访问图形界面或配置了远程连接,执行jconsole <PID>后,在“内存”页签可以直观地看到堆内存的实时曲线、已用大小和最大大小。
4. MAT分析OOM
启动 MAT 后,点击 File → Open Heap Dump,选择你的 .hprof 文件。
打开后可以直接查看 Leak Suspects Report(泄漏嫌疑报告),或者使用 Dominator Tree(支配树)来快速定位占用内存最多的对象。