基于 JDK 1.8 的垃圾回收机制详解
垃圾回收(Garbage Collection,简称 GC)是 Java 虚拟机(JVM)的核心功能,用于自动管理内存。JDK 1.8 的 GC 机制基于分代回收思想,将堆内存分为年轻代(Young Generation)和老年代(Old Generation),分别采用不同的垃圾回收器和策略。本文将按年轻代和老年代分类,详细分析 JDK 1.8 支持的垃圾回收器、回收策略及其优劣。
一、年轻代垃圾回收器
年轻代主要存储生命周期较短的对象,回收频率较高。JDK 1.8 提供了以下年轻代垃圾回收器:
-
Serial(串行回收器)
- 回收策略:标记-复制(Mark-Copy)算法,单线程执行。
- 特点:将存活对象复制到 Survivor 空间,清理 Eden 和已用 Survivor 空间。
- 参数 :
-XX:+UseSerialGC
。 - 优点:实现简单,适合单核 CPU 或小内存场景。
- 缺点:单线程导致回收效率低,停顿时间较长。
-
ParNew(并行新世代回收器)
- 回收策略:标记-复制算法,多线程并行执行。
- 特点:Serial 的多线程版本,常与 CMS 搭配使用。
- 参数 :
-XX:+UseParNewGC
。 - 优点:多线程提升回收效率,适合多核环境。
- 缺点:仍需 Stop-The-World(STW),停顿时间随对象数量增加而延长。
-
Parallel Scavenge(并行回收器)
- 回收策略:标记-复制算法,多线程并行执行。
- 特点:注重吞吐量,可动态调整堆大小。
- 参数 :
-XX:+UseParallelGC
。 - 优点:高吞吐量,适合后台任务。
- 缺点:停顿时间较长,不适合低延迟场景。
-
G1(年轻代模式)
- 回收策略:标记-复制算法,基于 Region 分区,多线程执行。
- 特点:G1 将堆划分为多个 Region,年轻代区域动态调整,回收时优先处理垃圾最多的区域。
- 参数 :
-XX:+UseG1GC
。 - 优点:停顿时间可控,适合大堆内存。
- 缺点:吞吐量略低于 Parallel Scavenge。
年轻代回收策略总结
- 主要算法:标记-复制算法,通过将存活对象复制到 Survivor 空间实现快速回收。
- 特点:年轻代对象存活率低,复制成本小,效率高。
- 适用场景 :
- Serial:小型应用。
- ParNew/Parallel Scavenge:多核服务器。
- G1:大堆、低延迟需求。
二、老年代垃圾回收器
老年代存储生命周期较长的对象,回收频率较低,但每次回收涉及内存较多。JDK 1.8 提供了以下老年代垃圾回收器:
-
Serial Old(串行老年代回收器)
- 回收策略:标记-整理(Mark-Compact)算法,单线程执行。
- 特点:将存活对象压缩到老年代一端,清理碎片。
- 参数 :
-XX:+UseSerialGC
。 - 优点:无碎片,内存利用率高。
- 缺点:单线程,停顿时间长。
-
Parallel Old(并行老年代回收器)
- 回收策略:标记-整理算法,多线程并行执行。
- 特点:Parallel Scavenge 的老年代增强版。
- 参数 :
-XX:+UseParallelGC -XX:+UseParallelOldGC
。 - 优点:高吞吐量,无碎片,适合多核环境。
- 缺点:STW 停顿时间较长。
-
CMS(并发标记清除)
- 回收策略:标记-清除(Mark-Sweep)算法,部分阶段与应用线程并发执行。
- 特点:分为初始标记(STW)、并发标记、重新标记(STW)、并发清除四个阶段。
- 参数 :
-XX:+UseConcMarkSweepGC
。 - 优点:低停顿时间,适合交互式应用。
- 缺点:产生内存碎片,可能触发 Serial Old 退化回收。
-
G1(老年代模式)
- 回收策略:标记-整理算法(部分并发),基于 Region 分区。
- 特点:动态管理年轻代和老年代边界,优先回收垃圾最多的 Region。
- 参数 :
-XX:+UseG1GC
。 - 优点:低停顿、无碎片,适合大堆。
- 缺点:实现复杂,吞吐量稍逊于 Parallel Old。
老年代回收策略总结
- 主要算法 :
- 标记-整理(Serial Old、Parallel Old、G1):消除碎片,内存紧凑。
- 标记-清除(CMS):并发性强,但有碎片。
- 特点:老年代对象存活率高,整理或清除策略需权衡停顿与碎片。
- 适用场景 :
- Serial Old:小型应用。
- Parallel Old:高吞吐量需求。
- CMS:低延迟需求。
- G1:大堆、综合性能。
三、JDK 1.8 默认垃圾回收策略
在 JDK 1.8 的 Server 模式下,默认使用 Parallel Scavenge(年轻代)+ Parallel Old(老年代):
- 年轻代:标记-复制,多线程并行。
- 老年代:标记-整理,多线程并行。
- 目标:最大化吞吐量。
优缺点分析
- 优点 :
- 高吞吐量,适合批处理任务。
- 无碎片,内存利用率高。
- 缺点 :
- STW 停顿时间长,不适合低延迟应用。
- 调优复杂,需调整线程数和停顿目标。
四、总结与建议
JDK 1.8 的垃圾回收器按代际分工明确:
- 年轻代:Serial、ParNew、Parallel Scavenge、G1,均采用标记-复制算法,注重回收效率。
- 老年代:Serial Old、Parallel Old、CMS、G1,策略分为标记-整理和标记-清除,平衡停顿与碎片。
默认的 Parallel Scavenge + Parallel Old 适合高吞吐量场景,但对于低延迟需求,建议使用 CMS 或 G1。实际应用中,应根据堆大小、延迟要求和吞吐量目标选择合适的回收器,并通过参数(如 -XX:MaxGCPauseMillis
、-XX:GCTimeRatio
)优化性能。