Java垃圾回收器(GC):什么是垃圾回收?如何选择 G1、ZGC 与 Shenandoah?

admin 6711

Java垃圾回收器(GC):什么是垃圾回收?如何选择 G1、ZGC 与 Shenandoah?粉丝提问:

Java 的垃圾回收器(GC)有什么作用?G1、ZGC 和 Shenandoah 有什么区别?如何根据场景选择最适合的 GC?

本文将通过丰富的代码示例深入讲解垃圾回收(Garbage Collection)的核心概念,比较 G1、ZGC 与 Shenandoah 的特性,提供调优技巧,助你选择最适合的 GC。

正文一、什么是垃圾回收(GC)?垃圾回收(GC)是 Java 虚拟机(JVM)自动内存管理的一部分,用于回收不再使用的对象内存。

1. GC 的工作原理可达性分析:通过遍历引用链判断对象是否可达。内存回收策略:清理不可达对象的内存并整理堆空间。示例:GC 自动管理内存代码语言:javascript代码运行次数:0运行复制public class GCDemo {

public static void main(String[] args) {

// 创建一个对象

GCDemo demo = new GCDemo();

System.out.println("对象已创建:" + demo);

// 将引用置为 null,便于回收

demo = null;

// 强制调用垃圾回收(仅建议测试使用)

System.gc();

System.out.println("垃圾回收已触发");

}

@Override

protected void finalize() throws Throwable {

System.out.println("对象被回收:" + this);

}

} 作者名片 ✍️

博主:猫头虎全网搜索关键词:猫头虎作者微信号:Libin9iOak作者公众号:猫头虎技术团队更新日期:2024年12月16日🌟 欢迎来到猫头虎的博客 — 探索技术的无限可能!二、垃圾回收器的种类Java 提供多种垃圾回收器,每种都有其特点和适用场景。

1. G1 垃圾回收器特点:分代式回收,分区(Region)设计,用户可设置暂停时间目标。适用场景:需要低延迟的大型应用,如电商、游戏服务器。代码示例:使用 G1代码语言:javascript代码运行次数:0运行复制public class G1GCDemo {

public static void main(String[] args) {

System.out.println("G1 GC 示例启动");

for (int i = 0; i < 1_000_000; i++) {

byte[] data = new byte[1024 * 1024]; // 创建大对象

}

System.out.println("G1 GC 示例结束");

}

}启动参数:

代码语言:javascript代码运行次数:0运行复制java -XX:+UseG1GC -XX:MaxGCPauseMillis=100 G1GCDemo2. ZGC(Z Garbage Collector)特点:暂停时间通常低于 10ms,支持超大内存(16TB)。适用场景:延迟敏感和内存密集型应用。代码示例:使用 ZGC代码语言:javascript代码运行次数:0运行复制public class ZGCDemo {

public static void main(String[] args) {

System.out.println("ZGC 示例启动");

for (int i = 0; i < 1_000_000; i++) {

byte[] data = new byte[1024 * 1024]; // 创建大对象

}

System.out.println("ZGC 示例结束");

}

}启动参数:

代码语言:javascript代码运行次数:0运行复制java -XX:+UseZGC -Xmx16G ZGCDemo3. Shenandoah特点:并发压缩,暂停时间在 10ms~100ms 之间,适合混合负载。适用场景:中大型内存应用,兼顾延迟和吞吐。代码示例:使用 Shenandoah代码语言:javascript代码运行次数:0运行复制public class ShenandoahGCDemo {

public static void main(String[] args) {

System.out.println("Shenandoah GC 示例启动");

for (int i = 0; i < 1_000_000; i++) {

byte[] data = new byte[1024 * 1024]; // 创建大对象

}

System.out.println("Shenandoah GC 示例结束");

}

}启动参数:

代码语言:javascript代码运行次数:0运行复制java -XX:+UseShenandoahGC ShenandoahGCDemo4、GC 调优示例1. 控制 G1 的暂停时间通过 -XX:MaxGCPauseMillis 设置目标暂停时间。

代码示例代码语言:javascript代码运行次数:0运行复制java -XX:+UseG1GC -XX:MaxGCPauseMillis=50 -Xmx4G G1GCDemo2. 监控垃圾回收性能使用 GC 日志分析回收行为。

启动参数代码语言:javascript代码运行次数:0运行复制java -Xlog:gc* -XX:+UseG1GC G1GCDemo输出示例代码语言:javascript代码运行次数:0运行复制[0.048s][info][gc] GC pause (G1 Evacuation Pause) (young)

[0.050s][info][gc] GC pause (G1 Mixed) (to-space exhausted)3. 在 ZGC 中优化内存使用通过 -Xmx 设置堆内存上限,优化内存分配。

代码示例代码语言:javascript代码运行次数:0运行复制java -XX:+UseZGC -Xmx8G ZGCDemo 作者名片 ✍️

博主:猫头虎全网搜索关键词:猫头虎作者微信号:Libin9iOak作者公众号:猫头虎技术团队更新日期:2024年12月16日🌟 欢迎来到猫头虎的博客 — 探索技术的无限可能!三、G1、ZGC 与 Shenandoah 对比特性

G1

ZGC

Shenandoah

暂停时间

可控(用户设置目标)

极低(10ms 以下)

较低(10ms~100ms)

并发回收

部分并发

几乎全并发

大部分并发

内存大小支持

大型内存(4GB~16TB)

超大内存(16TB)

中大型内存(1GB~10TB)

适用场景

在线系统

实时性要求高的系统

混合负载系统

性能稳定性

较高

极高

较高

四、如何选择适合的垃圾回收器?1. 根据应用延迟需求低延迟场景:选择 ZGC 或 Shenandoah。延迟可控场景:选择 G1,通过 -XX:MaxGCPauseMillis 设置目标暂停时间。2. 根据内存大小大内存(> 4GB):推荐 G1 或 ZGC。超大内存(> 10TB):优先选择 ZGC。3. 根据吞吐与并发需求吞吐优先:选择 G1 或 Shenandoah,适合高吞吐负载场景。并发优先:选择 ZGC,减少垃圾回收对应用的干扰。五、GC 调优技巧与常见问题1. 调优 G1 回收器常用参数-XX:MaxGCPauseMillis=

GC 日志:通过 -Xlog:gc* 启用详细 GC 日志。监控工具:如 JVisualVM、JConsole 或 Java Flight Recorder。Q2:为什么 ZGC 回收时间短?A:ZGC 几乎所有回收操作都在并发完成,避免了全停顿。

Q3:G1 为什么比 CMS 更适合低延迟场景?A:G1 的分区式收集和暂停时间目标设计,使其更适合延迟敏感的场景。

六、总结选择垃圾回收器的关键点:

根据 延迟需求:延迟敏感选 ZGC,低延迟选 Shenandoah。根据 内存大小:大内存选 G1,超大内存选 ZGC。根据 工作负载类型:混合负载选 Shenandoah,高吞吐负载选 G1。