Java虚拟机(JVM)垃圾回收机制(GC)详解(下)——垃圾收集器

HotSpot 常用的垃圾收集器

我们昨天早下班了,很惭愧,今天接着讲具体的垃圾回收器,先把昨天的图和文章放上来。再问一遍:就这配色,不配获得一个赞么?

Java虚拟机(JVM)的垃圾回收机制(GC)详解(上)

在这里插入图片描述

Serial收集器

  • 运行区域: 新生代
  • 主要特点: 单线程,采用上篇文章提到的复制算法进行清理,并且清理时要停掉所有的用户线程,也就是系统会停顿。

ParNew收集器

  • 运行区域: 新生代
  • 主要特点: Serial收集器收集器的多线程版本,它运行是也会停掉所有的用户线程,只是相当于有了多个清扫工人来打扫。但需要注意的是,在单CPU下,还是Serial收集器比较好,因为单CPU情况会频繁产生线程切换的开销,所以大家一定要根据不同业务场景进行选择,例如客户端比较适合Serial收集器,服务器比较适合ParNew收集器。

Parallel Scavenge收集器

  • 运行区域: 新生代
  • 主要特点: 他的运行方式和ParNew收集器很像,都是多线程进行垃圾收集,进行垃圾收集时就会停掉所有的用户线程。主要的不同在于,他给我们了一些设置值项让我们可以控制GC的停顿时间(例如,-XX:MaxGCPauseMillis 参数)
    当然了,事情都是有舍有得,我们希望他每次停顿的时间短,那么它运行的次数就会多,就比如你想保洁阿姨快点清扫完,那他就得每天常来扫,不然垃圾多了清扫时间就会长,这样一来总体算下来阿姨清扫的总时长也会增加(因为会频繁切换)。那如何去折中呢?GCTimeRatio参数就代表了GC时间占程序运行时间的一个比例(如果我们设置为20,那就代表GC占总时间的1/(20+1)
    其实,除了多来几次还有其他减少停顿时间的方式,例如缩小新生代的大小,这个应该容易理解,屋子小了打扫的自然就快了。-XX:+UseAdaptiveSizePolicy 参数被设置后JVM就可以根据我们设定的目标(GCTimeRatioMaxGCPauseMillis),对新生代的大小(-Xmn)、Eden与Survivor区的比例(-XX:SurvivorRatio)、晋升老年代对象年龄(-XX:PretenureSizeThreshold)等细节参数进行自动调节了。

Serial Old收集器

  • 运行区域: 老年代
  • 主要特征: Serial Old是Serial收集器的老年代版本,它也是单线程的,采用的算法主要是标记-整理。

Parallel Old收集器

  • 运行区域: 老年代
  • 主要特征: Parallel Old是Parallel Scavenge收集器的老年代版本。

CMS收集器(Concurrent Mark Sweep)

  • 运行区域: 老年代
  • 主要特征: 他主要应用了标记—清除算法,他的主要目标是让系统停顿最短的时间。
  • 运作流程:
  1. 初始标记:时间短,需要停用户线程,标记一下GC Roots能直接关联到的对象
  2. 并发标记:时间长,不需要停用户线程,进行GC RootsTracing的过程
  3. 重新标记:时间短,主要进行用户线程运行时产生变化的对象标记
  4. 并发清除:时间长,和用户线程一起运行
    在这里插入图片描述
  • 优点: 停顿时间短
  • 缺点: 1. 占用系统资源(并发执行占用资源)、2. 无法清理浮动垃圾(并发清除时产生的垃圾)、3. 会产生碎片(标记清除算法本身的问题,可设置 -XX:CMSFullGCsBeforeCompaction 参数,在几次Full GC时进行压缩空间整理碎片。)

G1收集器

  • 运行区域: 新生代 老年代
  • 主要特点: 分代收集,自己就可以对不同寿命的的对象采用不同的回收策略。空间整合,G1将内存划分为多个Region,这些Region有些是老年代有些是新生代,并不连续。整体上是“标记整理”算法,两个Region之间是“复制算法”,因此并不会产生碎片。可预测的停顿,我们可以对GC停顿时间进行指定。
  • 运行流程:
  1. 初始标记:标记一下GC Roots能直接关联到的对象,并且修改TAMS(Next Top at Mark Start)的值,让下一阶段用户程序并发运行时,能在正确可用的Region中创建新对象,这阶段需要停顿线程。
  2. 并发标记:GC Root开始对堆中对象进行可达性分析,记录到Remembered Set Logs里面
  3. 最终标记:把Remembered Set Logs的数据合并到Remembered Set中。
  4. 筛选回收:对各个Region的回收价值和成本进行排序,根据用户所期望的GC停顿时间来制定回收计划。
  • 使用提示: G1的目的是为了优化停顿时间,当Java堆很大时我们很难通过Parallel Scavenge指定停顿时间,如果我们考虑的是吞吐量优先,那G1的优势就不是很明显了。

协同配合

我们可以开文章最开始的那个图,用红线相连得就是可以用来搭配使用的垃圾回收器。

总结

我们先来个表格总结一下各种垃圾回收器的特点和应用的场景:
JVM GC总结
终于,写完了,撒花~(其实还有关于对象空间分配,不过想拖一拖:))

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

从前慢慢慢死了

打钱!一分也行啊!!!

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

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

打赏作者

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

抵扣说明:

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

余额充值