Full GC全解析教程,涵盖触发机制、问题诊断、调优策略和实战案例:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nsRlZAi8-1741613536305)(https://plumbr.io/wp-content/uploads/2016/01/g1-06-full-collection.png)]
维度 | Young GC | Full GC |
---|---|---|
回收范围 | 仅新生代 | 整个堆+元空间 |
触发频率 | 高 | 低 |
耗时 | 短(通常<100ms) | 长(可能秒级) |
收集器影响 | 不同算法差异小 | 算法差异显著 |
收集器 | Full GC触发条件 | 处理方式 |
---|---|---|
Serial | 老年代剩余空间 < 历次晋升平均大小 | Mark-Compact |
CMS | 并发模式失败 | Serial Old |
G1 | 堆内存不足且无法回收足够区域 | Full GC (Serial) |
ZGC | 无传统Full GC概念 | 全阶段并发处理 |
启用参数:
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/path/to/gc.log
典型日志分析:
2024-03-20T14:23:45.731+0800: [Full GC (Metadata GC Threshold)
[PSYoungGen: 43520K->0K(611648K)]
[ParOldGen: 278432K->259872K(1398272K)] 321952K->259872K(2009920K),
[Metaspace: 105676K->105676K(1056768K)], 1.456736 secs]
# 统计Full GC次数与耗时
jstat -gcutil 2000
# 输出示例
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0.0 100.0 99.6 98.3 99.8 91.2 217 5.97 3 4.23 10.20
关键指标:
特征:
诊断步骤:
jmap -dump:live,format=b,file=heapdump.hprof
特征:
代码示例:
// 错误示例:大对象直接进入老年代
List cache = new ArrayList<>();
cache.add(new byte[1024*1024*50]); // 50MB对象
特征:
诊断命令:
jstat -gcmetacapacity
问题类型 | 调优参数 | 说明 |
---|---|---|
内存泄漏 | -XX:+HeapDumpOnOutOfMemoryError | 内存溢出时自动转储 |
老年代不足 | -XX:MaxTenuringThreshold=5 | 降低晋升阈值 |
元空间溢出 | -XX:MaxMetaspaceSize=512m | 限制元空间上限 |
大对象问题 | -XX:PretenureSizeThreshold=1048576 | 超过1MB直接进老年代 |
收集器优化 | -XX:+UseG1GC | 切换到G1收集器 |
# 基础配置
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:InitiatingHeapOccupancyPercent=45
# 内存区域设置
-XX:G1HeapRegionSize=4m
-XX:G1ReservePercent=15
现象:
分析步骤:
修复方案:
// 使用弱引用缓存
Map> cache = new ConcurrentHashMap<>();
现象:
诊断方法:
# 监控Native内存
pmap -x | grep anonymous
解决方案:
-XX:NativeMemoryTracking=detail
jcmd VM.native_memory
给出GC日志片段:
[Full GC (Ergonomics)
[PSYoungGen: 0K->0K(764416K)]
[ParOldGen: 259872K->259872K(1398272K)] 259872K->259872K(2162688K),
[Metaspace: 105676K->105676K(1056768K)], 2.345 secs]
问题:
某系统配置:
-Xmx4g -Xms4g
-XX:+UseParallelGC
-XX:SurvivorRatio=8
现象:每小时发生3-4次Full GC,每次耗时1.5秒
问题:提出至少两种优化方案
1. 未有效回收内存(老年代259872K无变化)
2. 可能原因:
- 内存泄漏(对象被强引用)
- 堆外内存不足(如JNI分配)
- 系统内存资源耗尽
方案一:调整晋升策略
- 提高晋升阈值:-XX:MaxTenuringThreshold=10
- 增大Survivor区:-XX:SurvivorRatio=6
方案二:优化收集器
- 切换G1收集器:-XX:+UseG1GC
- 设置IHOP:-XX:InitiatingHeapOccupancyPercent=35
补充措施:
- 检查元空间配置:-XX:MaxMetaspaceSize=512m
- 添加内存溢出转储参数
通过本教程,能够:
✅ 准确诊断各类Full GC问题
✅ 合理配置JVM内存参数
✅ 掌握多收集器调优策略
✅ 制定系统化解决方案
附:性能调优黄金法则
预防优于治疗 → 监控发现趋势 →
小步渐进调整 → 多维验证效果