首页 > 图灵资讯 > 技术篇>正文

JVM垃圾收集器(三) ------ 垃圾回收器(一)

2023-07-09 16:58:31

垃圾回收器按线程分类

  • •串行垃圾回收器
  • •只允许一个CPU在同一时间内进行垃圾回收操作, 此时,直到垃圾收集工作结束,工作线程才暂停
  • •如果单CPU或较小的内存硬件平台不是特别优越,串行回收器的性能可以超过并行回收器和并发回收器
  • •客户端Client模式下的JVM应默认存在串行回收器
  • •并行垃圾回收器 ------- 同时使用多个CPU进行垃圾回收,从而增加吞吐量

两者的相同特征:都采用独家试验,会产生STW

图示:

JVM垃圾收集器(三) ------ 垃圾回收器(一)_CMS

按工作模式划分
  • •并发式垃圾回收器 交替引用线程,尽量减少应用程序的停顿时间
  • •独家垃圾回收器 一旦实施了垃圾收集线程, 在垃圾收集过程结束之前,停止应用程序中的所有用户线程

图示:

按照碎片分
  • •压缩垃圾回收器
  • •对存活对象进行压缩整理,消除回收碎片 ------ 重新分配对象的空间使用:指针碰撞
  • •非压缩垃圾收集器
  • •不进行空间整理 ------ 使用分配对象的方式:空闲列表

工作记忆分
  • •老年垃圾收集器
  • •年轻时的垃圾回收器
GC评估指标

衡量垃圾收集器的三个最重要的指标是:内存占用(Footprint)、吞吐量(Throughput)和延迟(Latency),三者共同构成了“不可能三角”。

  • •吞吐量:用户代码时间占总时间的比例
  • •垃圾收集费用:补充吞吐量、垃圾收集时间与总运行时间的比例
  • •暂停时间:垃圾收集程序的工作线程暂停时间
  • •收集频率:与应用程序的执行相比,收集操作的频率
  • •内存占用: Java堆所占内存大小
  • •快速:垃圾从收集到回收的时间

在设计GC算法时,我们必须明确自己的目标,对于吞吐量和暂停时间,我们只能取一个, 目前最大的目标是在最大吞吐量优化的情况下减少停顿时间。

垃圾收集器

垃圾收集器及其搭配规则:

JVM垃圾收集器(三) ------ 垃圾回收器(一)_垃圾收集_02

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(年轻一代)

本质上,ParNew收集器是Serial收集器的多线程并行版本

  • •并行回收
  • •在多CPU、在多核等情况下,垃圾收集可以更快地完成,提高程序的吞吐量
  • •目前,除了Serial,只有Parnew能够与CMS收集器合作
  • •-XX: +UserParNewGC手动设置

图示:

parallel Scavenge(年轻代)

目标:实现可控吞吐量(Throughput)。

吞吐量=运行用户代码时间/(运行用户代码时间+运行垃圾收集时间)

特点:

  • •吞吐量优先
  • •STW机制采用复制算法并行回收
  • •与Parnew不同,Parallel收集器的目标是达到可控的吞吐量,也被称为吞吐量优先的垃圾收集器
  • •与Parnew相比,添加了新的自适应策略
  • •高吞吐量能有效利用CPU时间,尽快完成操作任务,主要适用于后台操作,不需要太多交互。因此,它用于普通服务器

图示:

JVM垃圾收集器(三) ------ 垃圾回收器(一)_垃圾收集_03

parallel Old(老年代)

特点:

  • •STW机制采用标记压缩算法并行回收
  • •Java8中与Parallel的默认组合
  • •-XX: +UserAdapttiveSizePolicy 设置收集器的自适应调节策略
  • •在这种模式下,年轻一代、Eden和Survivor的比例将自动调整
  • •当手动调节困难时,可以考虑使用这种方法
  • •-XX: MaxGCPauseMllis 设置垃圾收集器最大停顿时间(STW停顿时间) ------ 该参数使用该谨慎
  • •-XX:GCTimeratio垃圾收集时间占总时间的比例

可以优先考虑吞吐量或处理器资源稀缺的情况Parallel ScavengeParallel Old这组收集器 合。

并发垃圾回收器CMS(老年)

JDK 5发布时,HotSpot推出了一款几乎具有划时代意义的垃圾收集器,在强交互应用中几乎可以称之为 —— CMS收集器

特点:

  • •低延迟
  • •第一次让垃圾收集线程和用户线程同时工作
  • •CMS垃圾收集算法采用标记清除算法,STW
  • •1.4不能与Parallel合作

工作原理:

  • •初始标记
  • •这一阶段将产生stw的短暂暂停
  • •这一阶段只标记了GCRoot直接关联的对象
  • •只是标记GC。 Roots可以快速直接关联的对象(所以stw时间很短)
  • •并发标记
  • •整个对象图的过程始于GCROOT的直接关联对象

  • •这个过程需要很长时间,但不需要停止用户线程,可以与垃圾收集线程并发执行

  • •重新标记

  • •由于并发标记阶段,程序的工作线程将与垃圾收集线程同时运行或交叉执行。因此,在此期间,由于用户程序运行而改变标记对象的哪一部分

  • •停顿时间通常比初始标记阶段长,但远比标记阶段短

  • •并发清除

  • •清除标记阶段已被判定为死亡岛饥饿对象,释放空间

  • •因为不需要移动生存对象,这个阶段也可以与用户线程并发

图示:

在整个过程中耗时最长的并发标记和并发清除阶段,垃圾收集器线程可以与用户线程一致 一般来说,CMS收集器的内存回收过程是与用户线程并发执行的

优点:

  • •并发回收(非独家)仍需在初始标记和再次标记中执行stw,但暂停时间不会太长
  • •由于并发标记和并发清除阶段不需要暂停工作,整体回收是低停顿

缺点:

  • •在CMS回收过程中,应确保用户线程有足够的内存,因为用户线程尚未中断
  • •因此,当堆达到一定阈值时,垃圾回收就开始了
  • •采用标记清除算法,因此回收后难免会产生一些内存碎片, 因此,当新对象分配空间时,只能选择内存分配

图示:

JVM垃圾收集器(三) ------ 垃圾回收器(一)_垃圾收集_04

注:使用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未 将来会被废弃

上一篇 java中关于继承强转的注意事项和坑
下一篇 浅谈同步、异步、回调函数之间的关系?

文章素材均来源于网络,如有侵权,请联系管理员删除。