手册 > 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 总耗时
相关推荐
转转技术团队13 分钟前
转转上门隐私号系统的演进
java·后端
【本人】38 分钟前
Django基础(二)———URL与映射
后端·python·django
Humbunklung1 小时前
Rust 模块系统:控制作用域与私有性
开发语言·后端·rust
WanderInk1 小时前
依赖对齐不再“失联”:破解 feign/BaseBuilder 错误实战
java·后端·架构
LaoZhangAI3 小时前
GPT-4o mini API限制完全指南:令牌配额、访问限制及优化策略【2025最新】
前端·后端
LaoZhangAI3 小时前
FLUX.1 API图像尺寸设置全指南:优化生成效果与成本
前端·后端
Kookoos3 小时前
ABP VNext + EF Core 二级缓存:提升查询性能
后端·.net·二级缓存·ef core·abp vnext
月初,3 小时前
SpringBoot集成Minio存储文件,开发图片上传等接口
java·spring boot·后端
KubeSphere4 小时前
全面升级!WizTelemetry 可观测平台 2.0 深度解析:打造云原生时代的智能可观测平台
后端
Frank_zhou4 小时前
Tomcat - 启动过程:类加载机制详解
后端