垃圾回收器按线程分类
- •串行垃圾回收器
- •只允许一个CPU在同一时间内进行垃圾回收操作, 此时,直到垃圾收集工作结束,工作线程才暂停
- •如果单CPU或较小的内存硬件平台不是特别优越,串行回收器的性能可以超过并行回收器和并发回收器
- •客户端Client模式下的JVM应默认存在串行回收器
- •并行垃圾回收器 ------- 同时使用多个CPU进行垃圾回收,从而增加吞吐量
两者的相同特征:都采用独家试验,会产生STW
图示:
- •并发式垃圾回收器 交替引用线程,尽量减少应用程序的停顿时间
- •独家垃圾回收器 一旦实施了垃圾收集线程, 在垃圾收集过程结束之前,停止应用程序中的所有用户线程
图示:
按照碎片分- •压缩垃圾回收器
- •对存活对象进行压缩整理,消除回收碎片 ------ 重新分配对象的空间使用:指针碰撞
- •非压缩垃圾收集器
•不进行空间整理 ------ 使用分配对象的方式:空闲列表
- •老年垃圾收集器
- •年轻时的垃圾回收器
衡量垃圾收集器的三个最重要的指标是:内存占用(Footprint)、吞吐量(Throughput)和延迟(Latency),三者共同构成了“不可能三角”。
- •吞吐量:用户代码时间占总时间的比例
- •垃圾收集费用:补充吞吐量、垃圾收集时间与总运行时间的比例
- •暂停时间:垃圾收集程序的工作线程暂停时间
- •收集频率:与应用程序的执行相比,收集操作的频率
- •内存占用: Java堆所占内存大小
- •快速:垃圾从收集到回收的时间
在设计GC算法时,我们必须明确自己的目标,对于吞吐量和暂停时间,我们只能取一个, 目前最大的目标是在最大吞吐量优化的情况下减少停顿时间。
垃圾收集器垃圾收集器及其搭配规则:
image-20210716141200120
- •两个收集器之间有连接,表明它们可以一起使用
- •Serial/Serial Old、Serial/CMS、ParNaw/Serial Old、Serial/CMS、Parallel Scavenge/Serial Old、Parallel Scavenge/Parallel Old、G1
- •其中,Serial 作为CMS,Old出现了“Old”Concurrent Mode Failure“失败的背后计划
- •由于维护和兼容性测试的成本,在JDK Serial将于8点举行+CMS、ParNew+Serial Old的两个组合声明是废弃的(JEP 173)并在JDK 这些组合的支持(JEP214)在9中被完全取消 , 即:移除。
- •(绿色虚线)JDK 14中:弃用Parallel Scavenge和Serial Old GC组合(JEP366)
- •(青色虚线)JDK 14.删除CMS垃圾回收器 (JEP 363 )
图示:
image-20210716150452591
Serial(年轻代)- •串行回收
- •最基本、最古老的收集器
- •新一代垃圾收集器在HotSpotClient模式下默认
- •内存回收采用复制算法、串行回收和STW机制
到目前为止,它仍然是HotSpot虚拟机在客户端模式下运行的默认新一代收集器。它比其他收集器好,简单高效(与其他收集器的单线程相比),因此Serial收集器是运行在客户端模式下的虚拟机的好选择。
Serial Old(老年代)- •串行回收和STW机制
- •内存回收算法采用标记压缩算法
- •默认情况下,在client模式下运行的老年垃圾回收器
- •在service模式下的两个用途
- •与新一代Parallel一起使用 Scavenge配合使用
- •作为老年CMS垃圾收集的背后方案
作用:
- •Hotspot虚拟机用于客户端模式下的Hotspot
- •在服务器端模式下:
- •在JDK 以及以前版本中的Parallel Scavenge收集器搭配使用
- •作为CM S 收集器失败时的后备计划,并发收集Concurent M ode Failure使用。
Serial和Serial Old总结:Old总结:
它是一种单线程垃圾回收器,它不仅指使用CPU,而且在运行过程中产生STW
优势:
- •简单而高效
- •在client模式下是一个不错的选择
XX: +UserserialGC指定年轻和老年人使用串行回收集器
总结:
- •使用单核CPU
- •一般来说,javaweb不会引用串行垃圾收集器
- •在单CPU的情况下,他比平行垃圾收集器更有效率
本质上,ParNew收集器是Serial收集器的多线程并行版本
- •并行回收
- •在多CPU、在多核等情况下,垃圾收集可以更快地完成,提高程序的吞吐量
- •目前,除了Serial,只有Parnew能够与CMS收集器合作
- •-XX: +UserParNewGC手动设置
图示:
parallel Scavenge(年轻代)目标:实现可控吞吐量(Throughput)。
吞吐量=运行用户代码时间/(运行用户代码时间+运行垃圾收集时间)
特点:
- •吞吐量优先
- •STW机制采用复制算法并行回收
- •与Parnew不同,Parallel收集器的目标是达到可控的吞吐量,也被称为吞吐量优先的垃圾收集器
- •与Parnew相比,添加了新的自适应策略
- •高吞吐量能有效利用CPU时间,尽快完成操作任务,主要适用于后台操作,不需要太多交互。因此,它用于普通服务器
图示:
特点:
- •STW机制采用标记压缩算法并行回收
- •Java8中与Parallel的默认组合
- •-XX: +UserAdapttiveSizePolicy 设置收集器的自适应调节策略
- •在这种模式下,年轻一代、Eden和Survivor的比例将自动调整
- •当手动调节困难时,可以考虑使用这种方法
- •-XX: MaxGCPauseMllis 设置垃圾收集器最大停顿时间(STW停顿时间) ------ 该参数使用该谨慎
- •-XX:GCTimeratio垃圾收集时间占总时间的比例
可以优先考虑吞吐量或处理器资源稀缺的情况Parallel Scavenge
加Parallel Old
这组收集器 合。
JDK 5发布时,HotSpot推出了一款几乎具有划时代意义的垃圾收集器,在强交互应用中几乎可以称之为 —— CMS收集器
特点:
- •低延迟
- •第一次让垃圾收集线程和用户线程同时工作
- •CMS垃圾收集算法采用标记清除算法,STW
- •1.4不能与Parallel合作
工作原理:
- •初始标记
- •这一阶段将产生stw的短暂暂停
- •这一阶段只标记了GCRoot直接关联的对象
- •只是标记GC。 Roots可以快速直接关联的对象(所以stw时间很短)
- •并发标记
•整个对象图的过程始于GCROOT的直接关联对象
•这个过程需要很长时间,但不需要停止用户线程,可以与垃圾收集线程并发执行
•重新标记
•由于并发标记阶段,程序的工作线程将与垃圾收集线程同时运行或交叉执行。因此,在此期间,由于用户程序运行而改变标记对象的哪一部分
•停顿时间通常比初始标记阶段长,但远比标记阶段短
•并发清除
•清除标记阶段已被判定为死亡岛饥饿对象,释放空间
•因为不需要移动生存对象,这个阶段也可以与用户线程并发
图示:
在整个过程中耗时最长的并发标记和并发清除阶段,垃圾收集器线程可以与用户线程一致 一般来说,CMS收集器的内存回收过程是与用户线程并发执行的
优点:
- •并发回收(非独家)仍需在初始标记和再次标记中执行stw,但暂停时间不会太长
- •由于并发标记和并发清除阶段不需要暂停工作,整体回收是低停顿
缺点:
- •在CMS回收过程中,应确保用户线程有足够的内存,因为用户线程尚未中断
- •因此,当堆达到一定阈值时,垃圾回收就开始了
- •采用标记清除算法,因此回收后难免会产生一些内存碎片, 因此,当新对象分配空间时,只能选择内存分配
图示:
注:使用Mark Sweeep会导致内存碎片,为什么不使用Mark呢? Compact呢?并发清除时,如果用compact整理内存,会导致内存位置发生变化。为了保证用户线程能够继续执行,有必要保证运行时对象地址不变。
- •CMS收集器对CPU资源非常敏感
- •CMS无法处理浮动垃圾 ------ 如果在并发阶段产生新的垃圾对象,CMS无法标记垃圾对象,最终导致垃圾对象未能及时回收
总结:
- •如果你想最小化内存和并行开支的使用 ------
Serial GC
- •如果你想最大化应用程序的吞吐量 ------
Parallel GC
- •如果你想最小化GC中断或停顿时间 ------
CMS GC
JDK后续变化:
- •JDK9被标记为
Deprecate
- •JDK14删除了CMS垃圾回收器
JDK Hotspot虚拟机9及以上版本使用 参数-XX:+UseConcM arkSweep 打开CM的GC 如果S收集器,用户将收到提示CM的警告信息 S未 将来会被废弃
