Develop

Java 虚拟机调优:从 GC 日志分析到内存泄漏排查

✎ -- 字 🕐 -- 分钟
字号

JVM 内存模型

Java 8+ 内存区域:

  • 堆(Heap):Young(Eden + S0/S1) + Old,对象分配的主战场
  • Metaspace:类元数据,替代了 PermGen
  • 线程栈:每个线程独享,存局部变量
  • 直接内存:NIO ByteBuffer,不受 GC 管理

GC 日志分析

# 启用 GC 日志 (Java 11+)
-Xlog:gc*=info:file=gc.log:time,level,tags

# 关键指标
[GC pause (G1 Evacuation Pause) 45.2ms]  # STW 时间
[Eden: 512M(512M)->0B(512M) Survivors: 64M->64M Heap: 3.2G(8G)->2.8G(8G)]

G1GC 核心参数

-XX:+UseG1GC
-XX:MaxGCPauseMillis=200    # 期望最大停顿(软目标)
-XX:G1HeapRegionSize=16m    # Region 大小
-XX:InitiatingHeapOccupancyPercent=45  # 触发 Mixed GC 的堆占用阈值
-XX:ConcGCThreads=4         # 并发 GC 线程数

内存泄漏排查流程

  1. jmap 生成 heap dumpjmap -dump:format=b,file=heap.hprof <pid>
  2. MAT/Eclipse Memory Analyzer:分析 Dominator Tree,定位大对象
  3. Arthas 线上诊断dashboard 看实时状态,heapdump 导出,thread -b 查死锁

常见 OOM 场景

  • 堆溢出:ThreadLocal 未清理、静态集合无限增长
  • Metaspace 溢出:动态代理类过多、Groovy 脚本频繁编译
  • 直接内存溢出:NIO 未释放、Netty 泄漏