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 线程数
内存泄漏排查流程
- jmap 生成 heap dump:
jmap -dump:format=b,file=heap.hprof <pid> - MAT/Eclipse Memory Analyzer:分析 Dominator Tree,定位大对象
- Arthas 线上诊断:
dashboard看实时状态,heapdump导出,thread -b查死锁
常见 OOM 场景
- 堆溢出:ThreadLocal 未清理、静态集合无限增长
- Metaspace 溢出:动态代理类过多、Groovy 脚本频繁编译
- 直接内存溢出:NIO 未释放、Netty 泄漏