一、JDK垃圾回收器概述
JDK的垃圾回收器(GC)负责自动回收堆内存中不再使用的对象,避免内存泄漏。不同GC适用于不同场景,核心差异在于吞吐量(单位时间处理请求数)、延迟(停顿时间)和内存占用。以下是JDK 8及以上版本的主流GC:
1. 串行垃圾回收器(Serial GC)
- 工作原理:单线程执行垃圾回收,回收时暂停所有应用线程(STW,Stop The World)。
- 适用场景:客户端应用(如桌面程序)、内存较小(≤100MB)的嵌入式系统。
- 启用参数:
-XX:+UseSerialGC。
2. 并行垃圾回收器(Parallel GC)
-
工作原理:多线程并行回收,关注吞吐量(CPU用于用户代码的时间占比)。新生代用复制算法,老年代用标记-整理算法。
-
适用场景:服务器端高吞吐量应用(如批量数据处理、科学计算),能接受一定停顿时间。
-
关键参数:
-XX:+UseParallelGC:启用新生代Parallel GC;-XX:+UseParallelOldGC:启用老年代Parallel Old GC;-XX:MaxGCPauseMillis:设置最大停顿时间目标(毫秒);-XX:GCTimeRatio:设置垃圾回收时间占比(默认99,即≤1%)。
3. 并发标记清除垃圾回收器(CMS GC)
-
工作原理:以最短停顿时间为目标,分四阶段:初始标记(STW)→ 并发标记→ 重新标记(STW)→ 并发清除。允许GC线程与应用线程并发执行。
-
适用场景:对响应时间敏感的Web服务器、交互式应用(如电商前端)。
-
缺点:产生内存碎片,可能导致频繁Full GC。
-
关键参数:
-XX:+UseConcMarkSweepGC:启用CMS GC;-XX:CMSInitialOccupancyFraction:老年代占用率达该百分比时触发CMS(默认68%);-XX:+UseCMSCompactAtFullCollection:Full GC后进行内存压缩(减少碎片)。
4. G1垃圾回收器(G1 GC)
-
工作原理:将堆划分为多个Region(大小1-32MB),优先回收“垃圾最多”的Region(Garbage First),兼顾吞吐量与延迟。新生代用复制算法,老年代用标记-整理算法。
-
适用场景:大内存(≥6GB)、低延迟应用(如微服务、大型电商系统),是JDK 9及以上的默认GC。
-
关键参数:
-XX:+UseG1GC:启用G1 GC;-XX:MaxGCPauseMillis:设置最大停顿时间目标(默认200ms);-XX:G1HeapRegionSize:设置Region大小(2的幂次方,如4M)。
5. ZGC垃圾回收器
- 工作原理:超低延迟(停顿时间≤10ms),采用着色指针(Colored Pointers)和读屏障(Load Barrier)技术,实现几乎并发的垃圾回收。
- 适用场景:对延迟极其敏感的应用(如金融交易系统、实时数据分析),支持TB级堆内存。
- 启用参数:
-XX:+UseZGC(JDK 11+支持)。
6. Shenandoah GC
- 工作原理:与ZGC类似,停顿时间与堆大小无关,通过并发复制算法减少停顿。
- 适用场景:红帽系JDK环境、超低延迟需求(如实时流处理)。
二、项目实战中如何选择与配置GC?
GC的选择需结合应用场景、硬件资源和性能需求,以下是具体策略:
1. 根据应用场景选择
- 客户端/嵌入式应用:选Serial GC(单线程开销小,适合小内存)。
- 高吞吐量服务器端:选Parallel GC(如批量任务、科学计算)。
- 低延迟Web应用:选G1 GC(默认,兼顾吞吐量与延迟)或CMS GC(适合旧系统)。
- 超大堆/实时应用:选ZGC(如金融交易、实时数据分析)。
2. 根据硬件资源选择
- 小内存(≤1GB) :选Serial GC(单线程更高效)。
- 大内存(≥6GB) :选G1 GC或ZGC(并行/并发回收更能发挥多核优势)。
3. 关键配置参数
-
堆内存设置:
-Xms:初始堆大小(建议与-Xmx相同,避免频繁扩容);-Xmx:最大堆大小(根据应用内存需求设置,如-Xmx4g);-Xmn:年轻代大小(建议为堆的1/3-1/2,如-Xmn2g)。
-
GC日志:启用GC日志监控性能,如
-Xlog:gc*(JDK 9+)或-XX:+PrintGCDetails(旧版本)。
4. 实战案例
-
案例1:电商Web应用(大内存、低延迟)
- 配置:
-Xms8g -Xmx8g -XX:+UseG1GC -XX:MaxGCPauseMillis=100 -Xlog:gc* - 说明:设置8GB堆内存,启用G1 GC,目标停顿时间100ms,输出GC日志用于调优。
- 配置:
-
案例2:金融交易系统(超低延迟)
- 配置:
-Xms16g -Xmx16g -XX:+UseZGC -Xlog:gc* - 说明:16GB堆内存,启用ZGC(停顿≤10ms),适合实时交易场景。
- 配置:
-
案例3:批量数据处理(高吞吐量)
- 配置:
-Xms4g -Xmx4g -XX:+UseParallelGC -XX:MaxGCPauseMillis=200 -XX:GCTimeRatio=99 - 说明:4GB堆内存,启用Parallel GC,优先保证吞吐量(垃圾回收时间≤1%)。
- 配置:
三、GC调优最佳实践
- 避免频繁Full GC:通过
-XX:CMSInitialOccupancyFraction(CMS)或-XX:MaxGCPauseMillis(G1)调整触发阈值,减少Full GC次数。 - 减少内存碎片:CMS启用
-XX:+UseCMSCompactAtFullCollection,G1通过标记-整理算法自动减少碎片。 - 监控与调优:使用工具(如GCViewer、GCEasy)分析GC日志,重点关注停顿时间、回收频率和内存使用率,逐步调整参数。
总结
JDK提供了多种GC,选择的核心是匹配应用场景:
- 小内存/客户端:Serial GC;
- 高吞吐量:Parallel GC;
- 低延迟:G1 GC(默认)/CMS GC;
- 超大堆/实时:ZGC。
实战中需结合硬件资源(内存、CPU)和性能需求(吞吐量、延迟),通过配置参数(如-Xmx、-XX:+UseG1GC)和监控(GC日志)优化性能。