JDK10 GC新特性,到底能带来多大提升?


请简述JDK8中常见垃圾收集器的工作原理及其不足?

这是许多Java开发者在面试中经常遇到的经典问题。虽然JDK8引入了G1垃圾收集器,极大改善了内存管理,但依然存在停顿时间长、并发性能有限等瓶颈,影响了高并发场景下应用的响应速度。为了解决这些问题,JDK9和JDK10对GC机制进行了多项优化,特别是在并发回收和监控能力上有了重要突破。

本文将以JDK9和JDK10的新GC特性为切入点,结合Visual VM中新增的对象直方图功能,详解如何利用这些工具提升Java应用的性能表现与问题排查效率。


一、JDK9/JDK10 在 GC上的主要改进

🔸主要更新

🔸 JEP 214:统一日志格式(Unified JVM Logging)
  • 引入统一的 -Xlog 命令行格式,可方便启用 GC、类加载、内存等模块的日志;
  • 替代 JDK8 中混乱的 -XX:+PrintGCDetails 等多个标志。
🔸 JEP 304:G1 并发 Full GC
  • 在 JDK9 中,G1 的 Full GC 终于开始支持并发执行,缓解了 STW(Stop The World)时长过长的问题;
  • 更适用于低延迟场景。
🔸 JEP 307:并行 GC 的线程局部分配缓冲(TLAB)优化
  • 对 Parallel GC 模式的对象分配过程进行改进;
  • 降低多线程争用,提高吞吐能力。
🚀 JDK10 新特性补充
  • 引入实验性的 ZGC(低延迟 GC),不过正式可用还要到后续版本;
  • G1 GC 中提升了对象分代晋升和 region 回收的效率。

✅ 与 JDK8 的主要差异

方面JDK8JDK9/JDK10
GC 日志PrintGCXX 系列参数统一的 -Xlog
G1 Full GC单线程 STW支持并发 Full GC
Survivor 分配传统区分 Eden/S0/S1增加直方图、动态阈值
Visual GC无对象年龄图新增对象 Histogram 视图

二、JDK10 的垃圾回收总结

✅ JDK10 中仍然支持的主要 GC 类型

垃圾收集器启用方式简介是否增强适用场景
Serial GC-XX:+UseSerialGC单线程执行 GC,简单高效✅ JEP 307 中优化了 TLAB小内存/单核系统
Parallel GC(吞吐量优先)-XX:+UseParallelGC多线程的 YGC 和 FGC,老牌高吞吐 GC✅ TLAB 提升并发效率服务端批处理,CPU 核心多
CMS(并发标记清除)-XX:+UseConcMarkSweepGC老年代并发回收,降低停顿时间❌ 计划废弃(已在 JDK9 标注 Deprecated)偏重响应时间的旧系统
G1 GC(默认)-XX:+UseG1GC(默认)分 Region 管理内存,目标低延迟✅ 支持并发 Full GC(JEP 304)服务端应用默认推荐
Epsilon GC(空 GC)-XX:+UseEpsilonGCJDK11 引入,仅用于性能测试❌ 不在 JDK10性能基准测试
ZGC实验性,JDK11 起可用亚毫秒延迟的 GC❌ 不在 JDK10超大堆/低延迟应用

🔍JDK10 中的垃圾收集器现状说明

📃两张图看懂垃圾收集器变更

JDK8中的垃圾收集器:

JDK8 垃圾收集器
Serial GC
Parallel GC
CMS (Concurrent Mark Sweep)
G1 GC
串行年轻代收集
串行老年代收集
并行年轻代收集
并行老年代收集
通常配合Parallel年轻代收集
并发标记-清除老年代收集
并行并发年轻代收集
分代整合的老年代收集

JDK10中的垃圾收集器:

JDK10 垃圾收集器
Serial GC
Parallel GC
G1 GC (改进版)
ZGC(实验性)
Shenandoah(部分版本支持)
串行年轻代收集
串行老年代收集
并行年轻代收集
并行老年代收集
并行并发年轻代收集
更高效的并发老年代收集
低停顿并发回收
基于Region的内存管理
低停顿并发回收
基于Region的内存管理
🖊JDK10做了哪些改动
  1. CMS 在 JDK9 中被标记为 Deprecated

    • JDK9 开始,CMS 已经不推荐使用,因为 G1 被认为是更现代的替代方案;

    • 不过 JDK10 中仍能使用,直到 JDK14 正式移除。

  2. Parallel GC 表现依然稳定

    • JDK10 中,JEP 307 对其 TLAB 做了线程局部优化,使其在多核服务器上表现更好;

    • 在吞吐量为主(如日志处理、大批量数据计算)的应用中仍很有市场。

  3. Serial GC 适用于容器、小型应用

    • 在容器内(低 CPU 限制)运行的小型 Java 服务中,Serial GC 依然简洁高效。

✳️ 如何选择垃圾收集器(JDK10)

场景推荐GC原因
响应时间敏感、低延迟G1 GC默认、支持并发 Full GC
吞吐量优先、大数据计算Parallel GC多线程,GC 停顿集中但快速
单线程、小内存场景Serial GC开销小,适合嵌入式或小容器
兼容旧系统CMS(非推荐)若未切换到 G1,可继续使用

三、VisualVM 查看对象直方图

步骤一:安装 Visual GC 插件

  • 打开 VisualVM→ 工具 → 插件 → 可用插件 → 勾选 Visual GC → 安装。

步骤二:连接目标 Java 进程

  • 在左侧找到 Java 应用,右键“Visual GC”;

步骤三:观察 Histogram 面板

  • 可实时查看不同年龄对象的内存占用趋势;
  • 横轴为对象年龄,纵轴为 Survivor 中内存占用;

步骤四:结合 GC 日志验证

建议搭配如下 JVM 参数一起使用:

-XX:+PrintGCDetails -XX:+PrintTenuringDistribution

高阶技巧:

  • 点击直方图柱子不可操作,但结合 Monitor 面板中 Eden/Old 使用情况可以更准确判断对象流向;
  • 多次采样或长时间监控,可发现是否存在内存泄漏或 Survivor 压力过大现象。

四、对象直方图 Histogram 功能

🔍 1. 什么是对象 Histogram?

Visual GC 插件中新增了对 Survivor 区中对象“年龄”的可视化直方图展示。每一列表示某个年龄层(即在 Survivor 区中经过的 GC 次数)的对象数量或占用内存。

📌 2. 核心参数解释

参数含义
Tenuring Threshold对象最多在 Survivor 区经历多少次 GC 后晋升到老年代(默认 15)
Max Tenuring ThresholdJVM 允许的最大值(也是 15)
Desired Survivor SizeSurvivor 区理想大小(如 47MB)
Current Survivor Size当前真实使用大小(单位:KB/MB)

✅ 示例截图解析

我们截一个启动中的jdk10应用的visual GC来看下:

image-1749296853038

在上图中,我们观察到:

  • Histogram 图中对象从年龄 1 到 6 有明显占用;
  • 年龄 7-15 全为空,说明很多对象未等老化晋升即已消失或已被提前晋升;
  • 当前 Survivor 区仅使用了 8KB,远小于期望值,表明 Survivor 区空间使用严重不足。

🔧 排查建议

观察现象可能问题建议调整
柱子集中在 1~2,后续为空Survivor 区太小,无法维持多次 GC 生命周期增大 Survivor 区,如 -XX:SurvivorRatio=6
Histogram 快速震荡、频繁变化有大量中等生命周期对象频繁移动优化对象生命周期,避免短命对象进入 Survivor
Old 区增长迅速但 Survivor 未满晋升阈值太低或晋升过早增加 -XX:MaxTenuringThreshold=15

五、总结

JDK9及JDK10引入的并发垃圾回收改进,有效缩短了应用停顿(STW)的时间,提升了整体系统响应速度,显著增强了用户体验。同时,Visual VM中新增加的对象直方图功能,为开发者提供了更直观的对象生命周期视图,帮助精准定位内存热点和潜在的内存泄漏问题。通过结合并发GC的性能提升与直方图的细粒度分析能力,我们不仅能够加速应用运行效率,还能更高效地进行问题排查和内存优化,保障Java应用的稳定性和持续健康发展。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值