命令汇总
shell
###### jdk8 查看jvm堆信息
# eg: jmap -heap 10712
jmap -heap <pid>
###### jdk21 查看jvm堆信息
# eg: jhsdb jmap --heap --pid 10712
jhsdb jmap --heap --pid <pid>
###### 查看当前生效的值
jinfo -flags <pid>
###### 实时监控 Java 虚拟机(JVM)垃圾回收(GC)统计信息 1000ms刷新一次
jstat -gc <pid> 1000
###### 监控老年代增长趋势
jstat -gcutil
###### 导出堆快照
jmap -dump:live,format=b,file=heap.hprof <pid>
优化参数汇总
ruby
###### 调整Survivor区比例(Eden:Survivor=6:1:1)
# 默认 SurvivorRatio=8 ,即Eden:Survivor=8:1:1
-XX:SurvivorRatio=6
###### 增大年轻代(如512MB)
-Xmn512m
###### 调整晋升阈值(避免过早晋升)
-XX:MaxTenuringThreshold=15
###### 切换至 G1 GC(如堆内存允许)改善 GC 体验
-XX:+UseG1GC
###### 打印 详细的垃圾回收日志,包括每次 GC 的类型、内存区域变化、耗时等信息
-XX:+PrintGCDetails
###### 打印 JVM 动态调整内存区域的决策日志(仅对支持自适应调整的 GC 如 Parallel Scavenge、G1 有效)
-XX:+PrintAdaptiveSizePolicy
###### 输出到文件
-Xloggc:/path/to/gc.log
###### 添加时间戳
-XX:+PrintGCDateStamps
# 基础诊断
###### 实时内存监控(每秒1次)
jstat -gcutil <pid> 1000
###### 线程快照(间隔5秒取3次)
for i in {1..3}; do jstack <pid> > thread_$i.log; sleep 5; done
###### 堆内存直方图(不触发Full GC)
jmap -histo:live <pid> > histo.log
调优目标
- 降低延迟(减少 GC 停顿时间)
- 提高吞吐量(最大化应用运行时间)
- 控制内存占用(避免 OOM 或资源浪费)
场景
-
内存泄漏排查 (Old Gen持续增长,频繁Full GC)
- 使用
jmap -dump:live,format=b,file=heap.hprof <pid>
导出堆快照 - 用 Eclipse MAT 或 JVisualVM 分析对象引用链
- 结合
jstat -gcutil
监控老年代增长趋势
- 使用
-
大数据计算(高吞吐优先)
ruby# Parallel GC 配置示例 java -Xms16g -Xmx16g \ -XX:+UseParallelGC \ -XX:ParallelGCThreads=8 \ -XX:+UseAdaptiveSizePolicy \ -jar app.jar
-
Web 服务(低延迟优先)
ini# G1 GC 配置示例 java -Xms8g -Xmx8g \ -XX:+UseG1GC \ -XX:MaxGCPauseMillis=100 \ -XX:InitiatingHeapOccupancyPercent=35 \ -jar app.jar
-
GC性能问题 (STW时间过长,吞吐量下降 )
- GC日志 +
jstat
实时监控
csharp# 1. 检查GC日志关键指标 [PSYoungGen: 819200K->0K(917504K)] 819200K->192304K(3056640K), 0.0364159 secs] # 关注点: # - 回收前后内存变化(如192304K残留) # - 耗时(0.036s) # - GC类型(Young/Full/Mixed) # 2. 计算GC效率 吞吐量 = 1 - (GC时间/总运行时间) 停顿时间 = Avg(STW时间)
- GC日志 +
-
CPU飙高 (线程长期满载)
top -Hp
+jstack
线程栈
perl# 1. 定位高CPU线程 top -Hp <pid> # 记录线程ID printf "%x\n" <tid> # 转16进制 # 2. 分析线程栈 jstack <pid> | grep -A20 <nid> # 匹配16进制ID # 3. 常见模式: # - 死循环:线程长期处于RUNNABLE # - 锁竞争:BLOCKED状态线程堆积
-
死锁/阻塞 (请求超时,线程池耗尽)
jstack
锁竞争分析
优化策略
问题现象 | 可能原因 |
---|---|
频繁 Full GC | 内存泄漏 / 大对象分配 |
Young GC 耗时过长 | Eden 区过大 / 对象存活率高 |
应用卡顿(STW 明显) | GC 算法不匹配场景 |
- gc关键指标 :
EU
、OU
、YGC
、FGC
、GCT
。 - 优化方向:根据数据调整堆大小、年轻代/老年代比例、GC 策略
避坑指南
- 避免过度调优:优先优化代码(如减少临时对象、缓存管理)。
- 不要盲目设大堆内存:可能引发长 GC 停顿(如 Full GC 耗时与堆大小正相关)。
- 生产环境测试 :任何参数调整需通过压测验证(推荐 JMeter / Gatling)
- 生产环境注意事项
-
安全采集数据
- 使用
jmap -dump:live
替代强制Full GC的-dump
- Arthas的
heapdump
命令支持动态采样
- 使用
-
低开销监控
bash
bash# 轻量级持续记录 nohup jstat -gcutil <pid> 300000 > gc.log & # 动态开启Debug jinfo -flag +PrintGCDetails <pid>
-
容器化环境适配
bash
bash# 在K8s中获取诊断信息 kubectl exec <pod> -- jstack 1 > thread.log kubectl cp <pod>:heap.hprof .
-
工具链
工具 | 用途 |
---|---|
JDK Mission Control | 深度性能分析 |
Async-Profiler | 低开销 CPU & 内存火焰图 |
GCViewer | GC 日志可视化分析 |
场景 | 工具 | 关键能力 |
---|---|---|
内存分析 | Eclipse MAT / JProfiler | 对象支配树、泄漏嫌疑报告 |
连续监控 | Prometheus + Grafana | 趋势可视化、自动告警 |
动态诊断 | Arthas | 方法调用追踪、热修复 |
生成的 gc 日志可通过工具可视化分析:
- GCEasy (在线工具):gceasy.io
- GCViewer (本地工具):github.com/chewiebug/G...
典型Case库
案例1:MetaSpace泄漏
- 现象 :
ClassLoader
数量持续增长 - 工具 :
jmap -clstats <pid>
- 根因:动态类生成未卸载
案例2:偏向锁竞争
- 现象:CPU高但利用率低
- 解决 :
-XX:-UseBiasedLocking
案例3:G1 Humongous分配
- 现象:Mixed GC频繁但回收效果差
- 定位 :
jcmd <pid> GC.heap_info
垃圾回收器选择
GC 类型 | 适用场景 | 关键参数 |
---|---|---|
G1 GC | 大堆(>4GB)、低延迟 | -XX:+UseG1GC |
ZGC | 超大堆(TB 级)、亚毫秒停顿 | -XX:+UseZGC |
Shenandoah | 低延迟、高吞吐 | -XX:+UseShenandoahGC |
Parallel | 高吞吐量(批处理) | -XX:+UseParallelGC |
执行示例
jmap -heap 10712
ini
F:\app\jdk\bin>jmap -heap 10712
Attaching to process ID 10712, please wait...
Debugger attached successfully.
Client compiler detected.
JVM version is 25.151-b12
using thread-local object allocation.
Mark Sweep Compact GC
Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 268435456 (256.0MB)
NewSize = 8388608 (8.0MB)
MaxNewSize = 89456640 (85.3125MB)
OldSize = 16777216 (16.0MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 12582912 (12.0MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 4294901760 (4095.9375MB)
G1HeapRegionSize = 0 (0.0MB)
Heap Usage:
New Generation (Eden + 1 Survivor Space):
capacity = 39518208 (37.6875MB)
used = 23951624 (22.84204864501953MB)
free = 15566584 (14.845451354980469MB)
60.60908429855929% used
Eden Space:
capacity = 35127296 (33.5MB)
used = 23267608 (22.189720153808594MB)
free = 11859688 (11.310279846191406MB)
66.23797060838386% used
From Space:
capacity = 4390912 (4.1875MB)
used = 684016 (0.6523284912109375MB)
free = 3706896 (3.5351715087890625MB)
15.577993819962687% used
To Space:
capacity = 4390912 (4.1875MB)
used = 0 (0.0MB)
free = 4390912 (4.1875MB)
0.0% used
tenured generation:
capacity = 87724032 (83.66015625MB)
used = 64147744 (61.176055908203125MB)
free = 23576288 (22.484100341796875MB)
73.12448201195312% used
18018 interned Strings occupying 1430480 bytes.
说明
堆配置 Heap Configuration
参数 | 值 | 说明 |
---|---|---|
MinHeapFreeRatio=40 |
40% | GC 后堆最小空闲比例(低于此值会扩容) |
MaxHeapFreeRatio=70 |
70% | GC 后堆最大空闲比例(高于此值会缩容) |
MaxHeapSize=256MB |
256MB | 堆最大容量 |
NewSize=8MB |
8MB | 年轻代初始大小 |
MaxNewSize=85.31MB |
85.31MB | 年轻代可扩展到的最大值 |
OldSize=16MB |
16MB | 老年代初始大小 |
NewRatio=2 |
2 | 老年代:年轻代=2:1(动态调整) |
SurvivorRatio=8 |
8 | Eden:Survivor=8:1:1(默认) |
MetaspaceSize=12MB |
12MB | 元空间初始大小 |
MaxMetaspaceSize=4096MB |
4096MB | 元空间最大容量 |
堆使用情况 Heap Usage
年轻代 New Generation
区域 | 容量 | 已使用 | 使用率 | 说明 |
---|---|---|---|---|
Eden | 33.5MB | 22.19MB | 66.24% | 新对象分配区,使用率正常 |
From Survivor | 4.1875MB | 0.65MB | 15.58% | 存放上次 GC 存活对象 |
To Survivor | 4.1875MB | 0MB | 0% | 下次 GC 的目标区域 |
- Eden 使用率 66% :新对象分配正常,未满。
- From Survivor 使用率 15.58% :存活对象较少,Minor GC 效率较高。
- To Survivor 空闲:等待下次 GC 复制存活对象。
老年代 Tenured Generation
参数 | 值 | 说明 | |
---|---|---|---|
容量 | 83.66MB | 老年代当前大小 | |
已使用 | 61.18MB | 73.12% | 接近警戒线 |
空闲 | 22.48MB | 剩余空间 |
- 老年代使用率 73% :
- 如果持续增长,可能触发 Full GC(MSC 的 Full GC 会 STW)。
- 可能原因:
- 长期存活对象过多(如缓存、静态集合)。
- 对象过早晋升 (Survivor 区较小或
MaxTenuringThreshold
设置过低)。
jhsdb jmap --heap --pid 8104
ini
C:\WINDOWS\system32>jhsdb jmap --heap --pid 8104
Attaching to process ID 8104, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 21.0.6+8-LTS-188
using thread-local object allocation.
Garbage-First (G1) GC with 6 thread(s)
Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 805306368 (768.0MB)
NewSize = 1363144 (1.2999954223632812MB)
MaxNewSize = 482344960 (460.0MB)
OldSize = 5452592 (5.1999969482421875MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 22020096 (21.0MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 1048576 (1.0MB)
Heap Usage:
G1 Heap:
regions = 768
capacity = 805306368 (768.0MB)
used = 74662016 (71.2032470703125MB)
free = 730644352 (696.7967529296875MB)
9.27125612894694% used
G1 Young Generation:
Eden Space:
regions = 4
capacity = 145752064 (139.0MB)
used = 4194304 (4.0MB)
free = 141557760 (135.0MB)
2.8776978417266186% used
Survivor Space:
regions = 3
capacity = 4194304 (4.0MB)
used = 4090088 (3.9006118774414062MB)
free = 104216 (0.09938812255859375MB)
97.51529693603516% used
G1 Old Generation:
regions = 66
capacity = 88080384 (84.0MB)
used = 66377624 (63.302635192871094MB)
free = 21702760 (20.697364807128906MB)
75.36027999151321% used
说明
堆配置 Heap Configuration
参数 | 值 | 说明 |
---|---|---|
MinHeapFreeRatio=40 |
40% | GC 后堆最小空闲比例(低于此值会扩容) |
MaxHeapFreeRatio=70 |
70% | GC 后堆最大空闲比例(高于此值会缩容) |
MaxHeapSize=768MB |
768MB | 堆最大容量 |
NewSize=1.3MB |
1.3MB | 年轻代初始大小 |
MaxNewSize=460MB |
460MB | 年轻代可扩展到的最大值 |
OldSize=5.2MB |
5.2MB | 老年代初始大小 |
NewRatio=2 |
2 | 老年代:年轻代=2:1(动态调整) |
SurvivorRatio=8 |
8 | Eden:Survivor=8:1:1(默认) |
MetaspaceSize=21MB |
21MB | 元空间初始大小 |
MaxMetaspaceSize=17592186044415 MB |
~16EB | 元空间最大容量(几乎无限制) |
G1HeapRegionSize=1MB |
1MB | G1 的 Region 大小 |
-
G1 GC 特性:
- 堆被划分为多个 1MB 的 Region (共 768 个,对应
MaxHeapSize=768MB
)。 - 年轻代和老年代不再固定大小,而是由 多个 Region 动态组成。
- 堆被划分为多个 1MB 的 Region (共 768 个,对应
-
年轻代(Young Generation) :
- 初始
1.3MB
,最大可到460MB
。
- 初始
-
老年代(Old Generation) :
- 初始
5.2MB
,当前占用84MB
(75.36%
使用率)
- 初始
Heap Usage(堆使用情况)
(1) G1 Heap(整个堆)
参数 | 值 | 说明 | |
---|---|---|---|
Regions | 768 | 总 Region 数量 | |
Capacity | 768MB | 堆总容量 | |
Used | 71.2MB | 9.27% | 当前使用量 |
Free | 696.8MB | 90.73% | 剩余空间 |
- 堆使用率极低(9.27%) ,说明应用当前内存压力很小。
(2) G1 Young Generation(年轻代)
区域 | Regions | 容量 | 已使用 | 使用率 | 说明 |
---|---|---|---|---|---|
Eden | 4 | 4MB | 4MB | 2.88% | 新对象分配区 |
Survivor | 3 | 3MB | 3.9MB | 97.52% | 存放上次 GC 存活对象 |
- Eden 使用率极低(2.88%) :新对象分配很少。
- Survivor 使用率 97.52% :几乎满,但 G1 会动态调整 Survivor 数量。
(3) G1 Old Generation(老年代)
参数 | 值 | 说明 | |
---|---|---|---|
Regions | 66 | 老年代占 66 个 Region | |
Capacity | 84MB | 老年代当前容量 | |
Used | 63.3MB | 75.36% | 接近警戒线 |
Free | 20.7MB | 剩余空间 |
-
老年代使用率 75% :
- G1 的 默认触发阈值(InitiatingHeapOccupancyPercent)为 45% ,但当前未触发 Mixed GC(可能因 IHOP 动态调整)。
- 如果持续增长,可能触发 Mixed GC(回收老年代 Region)。
jstat -gc 8104 1000
yaml
C:\WINDOWS\system32>jstat -gc 8104 1000
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT CGC CGCT GCT
0.0 1024.0 0.0 139.4 100352.0 20480.0 59392.0 45831.0 53696.0 52504.0 6912.0 6431.4 81 0.110 1 0.023 54 0.093 0.226
0.0 1024.0 0.0 139.4 100352.0 22528.0 59392.0 45831.0 53696.0 52504.0 6912.0 6431.4 81 0.110 1 0.023 54 0.093 0.226
0.0 1024.0 0.0 139.4 100352.0 22528.0 59392.0 45831.0 53696.0 52504.0 6912.0 6431.4 81 0.110 1 0.023 54 0.093 0.226
说明
列名 | 含义 | 单位 |
---|---|---|
S0C | Survivor 0 区当前容量(Capacity) | KB |
S1C | Survivor 1 区当前容量 | KB |
S0U | Survivor 0 区已使用量(Used) | KB |
S1U | Survivor 1 区已使用量 | KB |
EC | Eden 区当前容量 | KB |
EU | Eden 区已使用量 | KB |
OC | 老年代(Old)容量 | KB |
OU | 老年代已使用量 | KB |
MC | 元空间(Metaspace)容量 | KB |
MU | 元空间已使用量 | KB |
YGC | 年轻代 GC 次数(Young GC Count) | 次 |
YGCT | 年轻代 GC 总耗时(Young GC Time) | 秒 |
FGC | Full GC 次数 | 次 |
FGCT | Full GC 总耗时 | 秒 |
GCT | 所有 GC 总耗时 | 秒 |