← 返回首页

GC调优实战

📂 java ⏱ 1 min 180 words

GC调优实战

GC调优是Java性能优化的核心环节,合理的GC配置能显著降低延迟和提高吞吐量。

GC日志分析

# 启用GC日志(JDK11+)
java -Xlog:gc*:file=gc.log:time,uptime,level,tags \
     -jar app.jar

# 分析GC日志
# 使用GCEasy在线分析:https://gceasy.io
# 或使用GCViewer

常用GC收集器

收集器 算法 适用场景 参数
Serial 串行复制 单核/小内存 -XX:+UseSerialGC
Parallel 并行复制 吞吐量优先 -XX:+UseParallelGC
CMS 并发标记清除 低延迟 -XX:+UseConcMarkSweepGC
G1 分区+复制 大内存+低延迟 -XX:+UseG1GC
ZGC 染色指针+读屏障 超低延迟 -XX:+UseZGC
Shenandoah 转发指针 超低延迟 -XX:+UseShenandoahGC

G1调优

# G1推荐配置
java -XX:+UseG1GC \
     -XX:MaxGCPauseMillis=200 \
     -XX:G1HeapRegionSize=16m \
     -XX:InitiatingHeapOccupancyPercent=45 \
     -XX:G1ReservePercent=10 \
     -Xms8g -Xmx8g \
     -jar app.jar

G1调优示例

// 监控GC情况
public class GCMonitor {
    @Scheduled(fixedRate = 5000)
    public void monitorGC() {
        List<GarbageCollectorMXBean> gcBeans =
            ManagementFactory.getGarbageCollectorMXBeans();

        for (GarbageCollectorMXBean gcBean : gcBeans) {
            log.info("GC: {} Collections={}, Time={}ms",
                gcBean.getName(),
                gcBean.getCollectionCount(),
                gcBean.getCollectionTime());
        }
    }
}

调优策略

目标设定

/**
 * 调优目标
 * 1. 吞吐量:CPU用于执行用户代码的时间占比 > 95%
 * 2. 延迟:GC暂停时间 < 200ms(P99)
 * 3. 内存:避免Full GC或尽量减少
 */

内存分配策略

# 根据应用特点配置
# - 堆内存小于4G:使用Serial或Parallel
# - 堆内存4G-16G:使用G1
# - 堆内存>16G且延迟敏感:使用ZGC或Shenandoah

# 小应用
java -XX:+UseSerialGC -Xms256m -Xmx256m -jar app.jar

# 中等应用
java -XX:+UseG1GC -Xms4g -Xmx4g -jar app.jar

# 大型低延迟应用
java -XX:+UseZGC -Xms16g -Xmx16g -jar app.jar

GC日志解读

[GC (Allocation Failure) [PSYoungGen: 65536K->10752K(76288K)] 
 65536K->11020K(251392K), 0.0034567 secs]
 
# 解读:
# - GC类型:Allocation Failure(分配失败)
# - 年轻代:65536K -> 10752K(回收了54784K)
# - 堆总量:65536K -> 11020K
# - 耗时:0.0034567秒

常见GC问题

// 问题1:频繁Young GC
// 原因:新生代太小或对象分配过快
// 解决:增大-Xmn或调整G1RegionSize

// 问题2:Full GC频繁
// 原因:老年代空间不足
// 解决:增大堆内存或优化对象生命周期

// 问题3:GC暂停时间长
// 原因:堆内存过大或使用串行收集器
// 解决:使用G1/ZGC并设置合适的暂停目标

小结

GC调优需要根据应用特点选择合适的收集器,并通过GC日志分析持续优化配置。