粉丝提问:
JDK 17 和 JDK 21 在垃圾回收器(GC)上有什么优化?如何调整 GC 算法以提升应用性能?
本文将从 JDK 17 与 JDK 21 的垃圾回收改进出发,结合代码示例解析优化方案,并提供实际项目中的调优策略,帮助你提升应用性能。
JDK 17 与 JDK 21 提供了多个垃圾回收器,可以根据应用需求调整:
-XX:+UseG1GC # 启用 G1 GC
-XX:MaxGCPauseMillis=<时间> # 设置最大暂停时间
-XX:InitiatingHeapOccupancyPercent=<百分比> # 设置启动回收的堆占用百分比
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("示例结束");
}
}
启动参数:
java -XX:+UseG1GC -XX:MaxGCPauseMillis=100 -XX:InitiatingHeapOccupancyPercent=45 G1GCDemo
-XX:+UseZGC # 启用 ZGC
-Xms<size> # 设置堆初始大小
-Xmx<size> # 设置堆最大大小
-XX:SoftMaxHeapSize=<大小> # 设置软最大堆大小
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("示例结束");
}
}
启动参数:
java -XX:+UseZGC -Xmx16G -XX:SoftMaxHeapSize=8G ZGCDemo
-XX:+UseShenandoahGC # 启用 Shenandoah GC
-XX:ShenandoahGCHeuristics=<策略> # 设置启发式策略(如 compact、static 等)
public class ShenandoahGCDemo {
public static void main(String[] args) {
System.out.println("Shenandoah 调优示例");
for (int i = 0; i < 1_000_000; i++) {
byte[] data = new byte[1024 * 1024]; // 模拟分配大对象
}
System.out.println("示例结束");
}
}
启动参数:
java -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact ShenandoahGCDemo
通过启用 GC 日志,可以分析垃圾回收的详细行为。 启动参数:
-Xlog:gc* # 启用 GC 日志
-Xlog:gc*:file=gc.log:time,uptime,level,tags # 输出到文件
实时监控应用的堆内存使用和垃圾回收行为。
-Dcom.sun.management.jmxremote
参数。特性 | G1 | ZGC | Shenandoah |
---|---|---|---|
暂停时间 | 可控(用户设置目标) | 极低(10ms 以下) | 较低(10ms~100ms) |
吞吐量 | 较高 | 较高 | 高 |
并发回收 | 部分并发 | 几乎全并发 | 大部分并发 |
内存支持 | 4GB~16TB | 超大内存(16TB) | 1GB~10TB |
-Xms
和 -Xmx
),确保有足够的内存分配空间。A:ZGC 将大部分垃圾回收工作并发完成,仅有极少部分需要停顿。
JDK 17 与 JDK 21 中 GC 的优化点:
调优建议: