基于 JDK 1.8 的GC分析:垃圾回收器andGC算法


基于 JDK 1.8 的垃圾回收机制详解

垃圾回收(Garbage Collection,简称 GC)是 Java 虚拟机(JVM)的核心功能,用于自动管理内存。JDK 1.8 的 GC 机制基于分代回收思想,将堆内存分为年轻代(Young Generation)和老年代(Old Generation),分别采用不同的垃圾回收器和策略。本文将按年轻代和老年代分类,详细分析 JDK 1.8 支持的垃圾回收器、回收策略及其优劣。

一、年轻代垃圾回收器

年轻代主要存储生命周期较短的对象,回收频率较高。JDK 1.8 提供了以下年轻代垃圾回收器:

  1. Serial(串行回收器)

    • 回收策略:标记-复制(Mark-Copy)算法,单线程执行。
    • 特点:将存活对象复制到 Survivor 空间,清理 Eden 和已用 Survivor 空间。
    • 参数-XX:+UseSerialGC
    • 优点:实现简单,适合单核 CPU 或小内存场景。
    • 缺点:单线程导致回收效率低,停顿时间较长。
  2. ParNew(并行新世代回收器)

    • 回收策略:标记-复制算法,多线程并行执行。
    • 特点:Serial 的多线程版本,常与 CMS 搭配使用。
    • 参数-XX:+UseParNewGC
    • 优点:多线程提升回收效率,适合多核环境。
    • 缺点:仍需 Stop-The-World(STW),停顿时间随对象数量增加而延长。
  3. Parallel Scavenge(并行回收器)

    • 回收策略:标记-复制算法,多线程并行执行。
    • 特点:注重吞吐量,可动态调整堆大小。
    • 参数-XX:+UseParallelGC
    • 优点:高吞吐量,适合后台任务。
    • 缺点:停顿时间较长,不适合低延迟场景。
  4. G1(年轻代模式)

    • 回收策略:标记-复制算法,基于 Region 分区,多线程执行。
    • 特点:G1 将堆划分为多个 Region,年轻代区域动态调整,回收时优先处理垃圾最多的区域。
    • 参数-XX:+UseG1GC
    • 优点:停顿时间可控,适合大堆内存。
    • 缺点:吞吐量略低于 Parallel Scavenge。
年轻代回收策略总结
  • 主要算法:标记-复制算法,通过将存活对象复制到 Survivor 空间实现快速回收。
  • 特点:年轻代对象存活率低,复制成本小,效率高。
  • 适用场景
    • Serial:小型应用。
    • ParNew/Parallel Scavenge:多核服务器。
    • G1:大堆、低延迟需求。

二、老年代垃圾回收器

老年代存储生命周期较长的对象,回收频率较低,但每次回收涉及内存较多。JDK 1.8 提供了以下老年代垃圾回收器:

  1. Serial Old(串行老年代回收器)

    • 回收策略:标记-整理(Mark-Compact)算法,单线程执行。
    • 特点:将存活对象压缩到老年代一端,清理碎片。
    • 参数-XX:+UseSerialGC
    • 优点:无碎片,内存利用率高。
    • 缺点:单线程,停顿时间长。
  2. Parallel Old(并行老年代回收器)

    • 回收策略:标记-整理算法,多线程并行执行。
    • 特点:Parallel Scavenge 的老年代增强版。
    • 参数-XX:+UseParallelGC -XX:+UseParallelOldGC
    • 优点:高吞吐量,无碎片,适合多核环境。
    • 缺点:STW 停顿时间较长。
  3. CMS(并发标记清除)

    • 回收策略:标记-清除(Mark-Sweep)算法,部分阶段与应用线程并发执行。
    • 特点:分为初始标记(STW)、并发标记、重新标记(STW)、并发清除四个阶段。
    • 参数-XX:+UseConcMarkSweepGC
    • 优点:低停顿时间,适合交互式应用。
    • 缺点:产生内存碎片,可能触发 Serial Old 退化回收。
  4. 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)优化性能。

相关推荐
懵逼的小黑子7 小时前
Django 项目的 models 目录中,__init__.py 文件的作用
后端·python·django
小林学习编程8 小时前
SpringBoot校园失物招领信息平台
java·spring boot·后端
java1234_小锋10 小时前
Spring Bean有哪几种配置方式?
java·后端·spring
柯南二号11 小时前
【后端】SpringBoot用CORS解决无法跨域访问的问题
java·spring boot·后端
每天一个秃顶小技巧12 小时前
02.Golang 切片(slice)源码分析(一、定义与基础操作实现)
开发语言·后端·python·golang
gCode Teacher 格码致知12 小时前
《Asp.net Mvc 网站开发》复习试题
后端·asp.net·mvc
Moshow郑锴14 小时前
Spring Boot 3 + Undertow 服务器优化配置
服务器·spring boot·后端
Chandler2415 小时前
Go语言即时通讯系统 开发日志day1
开发语言·后端·golang
有梦想的攻城狮15 小时前
spring中的@Lazy注解详解
java·后端·spring
野犬寒鸦16 小时前
Linux常用命令详解(下):打包压缩、文本编辑与查找命令
linux·运维·服务器·数据库·后端·github