【java虚拟机】垃圾收集器介绍

从Serial到G1,详述垃圾回收器的发展历程,包括单线程与多线程环境下的优化策略,以及不同垃圾回收算法的特点。关注吞吐量与停顿时间,介绍各收集器如CMS、G1的工作原理及优缺点。

垃圾回收器

收集器发展历程:Serial收集器—》Parallel收集器—》CMS收集器—》G1收集器
在进行垃圾回收的时候,会暂停所有的工作线程,直到垃圾回收完成,垃圾回收器的不断迭代为了优化减少停顿时间
在这里插入图片描述
主要关注:
1、是单线程环境下还是多线程
2、垃圾回收算法

在这里插入图片描述

Serial收集器

单线程收集器(进行回收时,暂停所有用户线程),运行在客户端
新生代采用复制算法
老年代采用标记整理算法
在这里插入图片描述

ParNew收集器

是Serial收集器的多线程版本(提高效率),运行在Server

特点:
多线程进行垃圾回收,其余行为(控制参数、收集算法、stop the world、对象分配规则、回收策略)与Serial收集器完全一致,随着CPU的数量增加,对于GC时系统资源的有效利用还是很有好处的,默认开启的收集线程数与CPU的数量相同。

控制参数:
-XX:ParallelGCThreads 参数限制垃圾收集线程

优势:
除了Serial收集器,只有他能与CMS收集器配合使用

在这里插入图片描述

Parallel Scavenge

并行多线程收集器(关注吞吐量)

特点:达到一个可控制的吞吐量(其他线程的关注点尽可能的缩短用户线程的停顿时间),吞吐量就是CPU用于运行用户代码的时间与CPU的总消耗时间的比值,
吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)

区别:
(其他线程)停顿时间越短,交互响应时间越快,用户体验越好
(此线程)高吞吐量则是高效利用CPU时间,尽快完成程序运算任务,适合后台运算

控制参数:
-XX:MaxGCPauseMillis 控制垃圾回收最大停顿时间
-XX:GCTimeRatio 设置吞吐量大小(0——100)

Serial Old收集器

Serial Old是Serial收集器的老年代版本,是一个单线程收集器、使用标记-整理算法,运行在Client端
在这里插入图片描述

Parallel Old收集器

Parallel Old收集器是Parallel Scavenge 收集器的老年代版本,是一个多线程收集器、使用标记-整理算法,JDK1.6后开始提供。

Parallel Old收集器的出现,使“吞吐量优先”收集器终于有了名副其实的组合。在吞吐量和CPU敏感的场合,都可以使用Parallel Scavenge/Parallel Old组合
使用时暂停用户线程
在这里插入图片描述

CMS收集器

CMS收集器是一种以获取最短回收停顿时间为目标的收集器,基于标记-清除算法实现(某些处理可以和用户线程进行并发处理

基于标记-清除算法(内存碎片),并发收集、低停顿,运作过程复杂,分4步:

  • 初始标记:仅仅标记GC Roots能直接关联到的对象,速度快,但是需要“Stop The World”
  • 并发标记:就是进行追踪引用链的过程,可以和用户线程并发执行
  • 重新标记:修正并发标记阶段因用户线程继续运行而导致标记发生变化的 那部分对象的标记记录,比初始标记时间长但远比并发标记时间短,需要“Stop The World”
  • 并发清除:清除标记为可以回收对象,可以和用户线程并发执行
    由于整个过程耗时最长的并发标记和并发清除都可以和用户线程一起工作,所以总体上来看,CMS收集器的内存回收过程和用户线程是并发执行的。

缺点:
对CPU资源非常敏感
并发收集器虽然不会暂停用户线程,但因为占用一部分CPU资源,还是会导致应用程序变慢,总吞吐量降低。CMS的默认收集线程数量是=(CPU数量+3)/4;当CPU数量多于4个,收集线程占用的CPU资源多于25%,对用户程序影响可能较大;不足4个时,影响更大,可能无法接受。无法处理浮动垃圾(在并发清除时,用户线程新产生的垃圾叫浮动垃圾),可能出现“Concurrent Mode Failure”失败。

并发清除时需要预留一定的内存空间,不能像其他收集器在老年代几乎填满再进行收集;如果CMS预留内存空间无法满足程序需要,就会出现一次“Concurrent Mode Failure”失败;这时JVM启用后备预案:临时启用Serail Old 收集器,而导致另一次Full GC的产生;产生大量内存碎片:
CMS基于“标记-清除”算法,清除后不进行压缩操作产生大量不连续的内存碎片,这样会导致分配大内存对象时,无法找到足够的连续内存,从而需要提前触发另一次Full GC动作。
在这里插入图片描述

G1收集器

收集器发展最前沿成果之一,可以运行于服务端和客户端

特征:

  • 并发与并行:能充分利用多CPU、多核环境的硬件优势,缩短停顿时间,能和用户线程并发执行。
  • 分代收集:G1可以不需要其他GC收集器的配合就能独立管理整个堆,采用不同的方式处理新生对象和已经存活一段时间的对象。
  • 空间整合:整体上看采用标记整理算法,局部看是采用复制算法(两个Region之间),不会有内存碎片,不会因为大对象找不到足够的连续空间而提前触发GC,这点优于CMS收集器
  • 可预测的停顿:除了追求低停顿还能建立可以预测的停顿时间模型,能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集器上的时间不超N毫秒,这点优于CMS收集器。

为什么能做到可预测的停顿?
是因为可以有计划的避免在整个java堆中进行全区域的垃圾收集。G1收集器将内存大小相等的独立区域(Region),新生代和老年代概念保留,但是已经不再物理隔离。G1跟踪各个Region获得其收集价值大小【注:《深入理解java虚拟机》这样解释:回收所获得的空间大小以及回收所需要的时间的经验值】,在后台维护一个优先列表;每次根据允许的收集时间,优先回收价值最大的Region(名称Garbage-First的由来):这就保证了在有限的时间内可以获取尽可能高的收集效率

回收过程步骤(与CMS较为相似):

  • 初始标记:仅仅标记GC Roots能直接关联到的对象,并修改TAMS(Next Top at Mark Start)的值,让下一阶短用户线程并发运行时能在正确可用的Region中创建新对象,需要“Stop The World”
  • 并发标记:从GC Roots开始进行可达性分析,找出存活对象,耗时长,可与用户线程并发执行
  • 最终标记:修正并发标记阶段因用户线程继续运行而导致标记发生变化的那部分对象的标记记录。并发标记时虚拟机将对象变化记录在线程Remember Set Logs里面,最终标记阶段将Remember Set Logs整合到Remember Set中,比初始标记时间长但远比并发标记时间短,需要“Stop The World”
  • 筛选回收:首先对各个Region的回收价值和成本进行排序,然后根据用户期望的GC停顿时间来定制回收计划,最后按计划回收一些价值高的Region中垃圾对象。回收时采用复制算法,从一个或多个Region复制存活对象到堆上的另一个空的Region,并且在此过程中压缩和释放内存;可以并发进行,降低停顿时间,并增加吞吐量。在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值