常见垃圾回收器解析

垃圾回收器基础分类

按线程数分类:
①串行垃圾回收器:
指同一时间段只有一个线程在进行垃圾回收工作,此时用户线程将因STW停止,等垃圾回收结束后恢复。
在单核或较小应用内存场合下比较合适。
②并行回收器:
指可以运用多个CPU同时执行垃圾回收工作,能提升应用的吞吐量。
在多核CPU机器上,并行回收器性能更好(工作期间同样有STW)

按工作模式分:
①并发式回收器:
并发式回收器和用户线程交替执行,尽可能减少STW引起的停顿
②独占式回收器:
一旦独占工作,停止所有用户线程,直到垃圾回收结束。

按碎片处理方式分:
①压缩式收集器:
回收完毕后,整理内存空间,避免内存碎片
②非压缩式收集器:
回收过程没有整理内存的步骤

按工作内存分:
①年轻代收集器
②老年代收集器

垃圾回收性能指标

①吞吐量:
运行用户程序的时间占总时间运行的比例(总运行时间=程序运行时间+垃圾回收时间)
②垃圾收集开销:
进行垃圾收集的时间占总运行时间的比例
③延迟:
执行垃圾回收时,程序的工作线程被暂停的时间
④收集频率:
相对于应用程序的执行,收集操作发生的频率
⑤内存占用:
Java堆区所占内存的大小
⑥快速:
一个对象从诞生到回收经历的时间

注:
a.①②③三条是重要指标,随着硬件发展,延迟的重要性日益凸显,内存占用可以忍耐,吞吐量随着垃圾回收运行对用户线程影响日益降低也又增加。但内存的扩大让GC执行的任务增多,GC时延迟也就更长。
b.吞吐量(越高越好)和延迟(越低越好)两者的矛盾:
若要求程序有高吞吐量,那么GC频率必须降低,但一次GC所执行的任务就增多,时间上升,延迟也就增加
若延迟低,就需要增加GC频率,会导致整个GC占用时间更多,吞吐量随之降低
现代回收器优先保证最大吞吐量,再降低延迟

垃圾回收器解析

Serial回收器:串行回收

①该回收器是最基本、历史最长的垃圾回收器
②作为Client模式下默认的年轻代垃圾回收器
③采用复制算法、串行回收和STW对年轻代进行回收
④还有针对老年代的Serial Old回收器,用了标记-压缩算法、串行回收、STW
优点:
简单,相对于其他单线程回收器更高效(因为不涉及线程交互的开销,专心进行垃圾回收)
缺点:
随着多核CPU的发展,串行回收器很少,因为执行回收将用户线程完全停止,很难接受

ParNew回收器:并行回收

ParNew是Serial的多线程版本,除了可以多线程进行垃圾回收,和Serial几乎没有区别
采用复制算法、并行回收和STW对年轻代进行回收

Parallel回收器:高吞吐

使用复制算法、并行回收和STW堆年轻代进行回收
方式和ParNew相同,但Parallel回收器目的是达到可控的吞吐量,它以吞吐量为优先,适合用于后台交互不多的任务,可以做到尽快完成程序任务的效果(它有自适应调节策略)
注:自适应调节策略:
JVM可以自动调整年轻代大小、Eden和S区的比例、晋升老年代对象的阈值年龄等

其还有ParallelOld回收器,采用标记-压缩算法,并行回收和STW机制对老年代进行垃圾回收

CMS回收器:低延迟

CMS关注点是尽可能缩短垃圾回收时用户线程的停顿时间,停顿时间越短(延迟越低),越适合和用户交互较多的程序(即响应速度较快)。
采用标记-清除算法、并发执行和STW对老年代进行垃圾回收。
工作过程:
①初始标记:该阶段进入STW,标记出GC Roots能直接关联到的对象,一旦标记完会先恢复被暂停的用户线程
②并发标记:依据第一步标记的直接关联对象,开启并发线程进行遍历挂在引用链上的对象。
③重新标记:由于并发标记是标记和用户线程并发执行,因此在清除前再进行一次标记,保证引用关系正确
④并发清除:并发清除标记到的垃圾对象
特点:
特点
①虽然CMS是并发回收,但初始标记和重新标记仍然需要STW暂停用户线程,但时间不长。(所有垃圾回收都需要STW,只能尽量减少,因为没有STW将难以确认对象之间的引用关系)
②由于最耗时的并发标记和并发清除都与用户线程并发执行,所以整体CMS是低延迟的
③在并发清除阶段,因为和用户线程并发执行,边回收垃圾边制造垃圾,所以在CMS并发清除阶段需要确保用户线程有足够的内存使用(所以CMS不能等到老年代满了再回收,需要设置阈值),当用户线程内存不足,会启用SerialOld对老年代垃圾回收
④CMS用标记清除算法,意味着每次清除会产生内存碎片,虽然标记-压缩算法不会产生内存碎片,但因为并发清除是并发状态,堆中对象移动后,用户线程持有的对象地址可能失效。

G1回收器:区域划分代式

G1优点

并行和并发
并行:在G1回收期间可以由多个GC线程工作,有效利用多核工作能力
并发:G1拥有与用户线程交替执行的能力,不会在整个回收阶段完全阻塞应用程序

分代分区收集
从分代看,G1仍属于分代型垃圾回收器,但从堆的角度看,它不要求年轻代或老年代连续、也不需要固定大小、固定数量。
G1将堆分为若干区域,这些区域包含逻辑上的年轻代和老年代(即G1回收兼顾老年代和年轻代)

空间整合
G1对内存回收以Region为基本单位,采用复制算法(但整体看作标记-压缩算法),可以避免内存碎片,有利于程序长时间运行,当Java堆非常大时,G1优势明显

可预测的停顿时间模型
G1除了追求低延迟意外,还可以建立可预测停顿时间模型,让使用者明确一定时间片段中,垃圾回收占的时间上限。
由于分区,G1可以只选部分Region回收,缩小了范围,后台维护优先价值列表,优先回收价值最大的Region

G1缺点

G1在用户运行时,为垃圾回收产生的内存占比、额外执行负载都相比更高。

Region概念

打破先前连续空间区分老年、年轻代,采取将堆划分为大小相同的Region。
除了延续Eden、S、Old,Region还多出H,主要用于存储大对象
设置H原因:对于堆中的大对象,默认直接分配到老年代,但若是一个短期存在的大对象,会有负面影响,为了解决问题,G1划分了H区,专门存储打对象,若一个H区装不下一个大对象,G1会寻找连续的H进行存储,通常H作为来年代的一部分看待

G1垃圾回收环节

①当年轻代Eden区用尽开启YoungGC,YoungGC是并行独占式回收期,暂停所有用户线程,启动多GC线程回收年轻代
②当堆内存达到一定值,开启老年代并发标记过程:并发标记同时进行YoungGC,线程将老年代存活对象标记并与用户线程并发执行
③标记完成后进行混合回收:G1将老年代存活对象移动到空闲空间,和年轻代不同,G1老年代不需要回收整个老年代,一次只需要扫描/回收一小部分老年代的Region,同时进行YoungGC

引用关系查找优化:记忆集合写屏障

①每个Region有一个对应的记忆集
②每个引用类型数据写操作时,会产生一个写屏障暂时中断操作
③检查将要写入的引用指向对象是否和该引用类型数据在不同Region
④若不同,通过卡表将引用信息记录到引用指向对象所在Region的记忆集中
⑤进行垃圾回收时,在GC Roots枚举范围内加入记忆集,就可以保证不进行全局扫描

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

魔幻音

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值