手册 > jvm 调优及问题排查 (未完待续)

命令汇总

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)

    1. 使用 jmap -dump:live,format=b,file=heap.hprof <pid> 导出堆快照
    2. Eclipse MATJVisualVM 分析对象引用链
    3. 结合 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时间)
  • 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关键指标EUOUYGCFGCGCT
  • 优化方向:根据数据调整堆大小、年轻代/老年代比例、GC 策略

避坑指南

  1. 避免过度调优:优先优化代码(如减少临时对象、缓存管理)。
  2. 不要盲目设大堆内存:可能引发长 GC 停顿(如 Full GC 耗时与堆大小正相关)。
  3. 生产环境测试 :任何参数调整需通过压测验证(推荐 JMeter / Gatling
  4. 生产环境注意事项
    1. 安全采集数据

      • 使用jmap -dump:live替代强制Full GC的-dump
      • Arthas的heapdump命令支持动态采样
    2. 低开销监控

      bash

      bash 复制代码
      # 轻量级持续记录
      nohup jstat -gcutil <pid> 300000 > gc.log &
      
      # 动态开启Debug
      jinfo -flag +PrintGCDetails <pid>
    3. 容器化环境适配

      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 日志可通过工具可视化分析:

典型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 动态组成
  • 年轻代(Young Generation)

    • 初始 1.3MB,最大可到 460MB
  • 老年代(Old Generation)

    • 初始 5.2MB,当前占用 84MB75.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 总耗时
相关推荐
Victor35612 分钟前
Redis(14)Redis的列表(List)类型有哪些常用命令?
后端
Victor35612 分钟前
Redis(15)Redis的集合(Set)类型有哪些常用命令?
后端
卷福同学13 分钟前
来上海三个月,我在马路边上遇到了阿里前同事...
java·后端
bobz9659 小时前
小语言模型是真正的未来
后端
DevYK10 小时前
企业级 Agent 开发实战(一) LangGraph 快速入门
后端·llm·agent
一只叫煤球的猫10 小时前
🕰 一个案例带你彻底搞懂延迟双删
java·后端·面试
冒泡的肥皂10 小时前
MVCC初学demo(一
数据库·后端·mysql
颜如玉11 小时前
ElasticSearch关键参数备忘
后端·elasticsearch·搜索引擎
卡拉叽里呱啦12 小时前
缓存-变更事件捕捉、更新策略、本地缓存和热key问题
分布式·后端·缓存
David爱编程12 小时前
线程调度策略详解:时间片轮转 vs 优先级机制,面试常考!
java·后端