JVM 垃圾回收是 Java 面试的高频考点。别再只说「标记-清除」了。
GC 算法的演进
- 标记-清除:最简单,但会产生内存碎片
- 标记-整理:清除后整理内存,解决了碎片问题
- 标记-复制:把存活对象复制到新区域,效率最高(新生代用的就是这种)
分代收集
JVM 把堆分成新生代(Young)和老年代(Old): - 新生代用复制算法(大部分对象朝生夕死) - 老年代用标记-整理算法
新生代又分 Eden、Survivor0、Survivor1。对象先在 Eden 分配,经过几次 GC 还活着就晋升到老年代。
经典 GC 组合
- Serial + Serial Old:单线程,适合客户端应用
- Parallel Scavenge + Parallel Old:多线程,追求吞吐量
- CMS + ParNew:低延迟,但已经废弃(JDK 14 移除了)
- G1:JDK 9 后默认,平衡吞吐量和延迟
- ZGC:JDK 15 正式版,亚毫秒级暂停(<1ms)
- Shenandoah:Red Hat 贡献的,跟 ZGC 类似
面试怎么答
- 先说 GC 的基本目的:回收不再使用的对象,释放内存
- 再说分代收集的原理
- 然后说常见的几种 GC 适合什么场景
- 最后提一下为什么要从 CMS 升级到 G1(CMS 的碎片问题、浮动垃圾)
加分项
能说清楚 G1 的 Region 设计——不固定 Eden/Survivor/Old 的大小,而是用多个 Region 动态分配。这使得 G1 的停顿时间可以预测(通过设置 MaxGCPauseMillis)。
GC 是 Java 性能优化的基础。理解了 GC 日志,你才能看懂线上为什么卡。
评论
评论已关闭。