JVM原理(五):JVM发展至今的七款垃圾收集器

收集算法是内存回收的方法论,那垃圾收集器就是内存回收的实践者

上图展示了七种作用于不同分代的收集器,如果两个收集器之间存在连线,就说明他们可以搭配使用。图中收集器所在的区域,则表示它是属于新生代收集器抑或是老年代收集器

1. Serial收集器

Serial收集器是最基础、历史悠久的收集器,同时他也是一个单线程工作的收集器。

优点:与其他收集器相比,简单而高效、它是所有收集器里消耗最小的,同时效率最高的单线程。

缺点:会“Stop the World”


当前:依旧是HotSpot虚拟机运行在客户端下默认的新生代收集器。

推荐:在客户端使用。


算法:标记-复制

2. ParNew收集器

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

优点:低概率出现“Stop the world”

缺点:存在线程交互的开销,效率比Serial低。


当前:JDK9前使用ParNew搭配CMS

推荐:服务端


算法:标记-复制

3. Parallel Scavenge收集器

派瑞啦斯堪瑞吉

Parallel Scavenge目标是达到一个可控制的吞吐量:

用户可以设置控制最大垃圾收集停顿时间,和直接设置吞吐量大小。


算法:标记-复制

4. Serial Old收集器

Serial Old收集器是Serial收集器的老年代版本,使用单线程。

优点:单线程,快

缺点:可能会出现“Stop the world”


当前:JDK5之前是Parallel+Scavenge的后备预案。

推荐:客户端


算法:标记-整理

5. Parallel old 收集器

Parallel Scavenge收集器的老年代版本,使用多线程并发收集。

优点:降低“Stop the world”的概率

缺点:加大系统资源的使用


当前:JDK5之前是Parallel+Scavenge的后备预案。

推荐:注重吞吐率和处理资源较为稀缺的环境。比如大数据


算法:标记-整理

6. CMS收集器

CMS收集器是一种以获取最短回收停顿时间为目标的收集器。

优点:并发收集、低停顿

缺点:CMS收集器对处理器资源非常敏感CMS无法处理“浮动垃圾”,有可能出现并发失败而进行Full GC标记-清除会产生大量碎片化空间


当前:JDK5之前是Parallel+Scavenge的后备预案。

推荐:系统停顿时间尽可能短,已给客户带来更好的交互体验。B/S系统


算法:标记-清除算法

标记阶段并发:增量更新


运作过程

  1. 初始标记:标记一下GC Roots能直接关联到的对象,速度很快,会“STW”

  2. 并发标记:从GC Roots的直接关联对象开始遍历整个对象图的过程,耗时较长

  3. 重新标记:为了修正并发标记期间,因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录。会“STW”

  4. 并发清除:清理删除标记阶段判断已经死亡的对象。

7. G1收集器

Garbage First ( 简称G1)收集器是垃圾收集器技术发展历史上的里程碑式的成果,它开创了收集 器面向局部收集的设计思路和基于Region的内存布局形式。被官方称之为“全能的垃圾回收器”。

目标:在延迟可控的情况下获得尽可能高的吞吐量。

特点:G1面向堆内存来组成回收集来进行回收,衡量标准不再是它属于哪个分代,而是哪块内存内存中存放的垃圾数量最多,回收收益最大,这就是G1收集器的Mixed GC模式。

Region堆:实现Mixed GC模式的关键。G1不再坚持固定大小以及固定数量的分代区域划分,而是把连续的Java堆划分为多个大小相等的独立区域(Region),每一个Region都可以根据需要,扮演新生代的Eden空间、Survivor空间,或者老年代空间。

Humongous区域:Region中还有一类特殊的Humongous区域,专门用来存储大对象,只要改对象大小超过Region容量一般就判定为大对象。

更具体的处理思路是让G1收集器去跟踪各个Region里面的垃圾堆积的“价值”大小,价值即回收所获得的空间大小以及回收所需时间的经验值,然后在后台维护一个优先级列表,每次根据用户设定允许的收集停顿时间(使用参数-XX: M axGCPauseMilis指定,默认值是200毫秒),优先处理回收价值收益最大的那些Region,这也就是“Garbage First”名字的由来。这种使用Region划分内存空间,以及具有优先级的区域回收方式,保证了G1收集器在有限的时间内获取尽可能高的收集效率。


缺点:

  1. 跨Region对象的回收要比其他收集器的效率低。

  2. 并发标记阶段,如果内存回收的速度赶不上内存分配的速度,G1会冻结用户线程,导致触发Full GC而产生的“STW”。


运行过程步骤:

  1. 初始标记( Initial Marking) :仅仅只是标记一下GC Roots能直接关联到的对象,并且修改TAMS指针的值,让下一阶段用户线程并发运行时,能正确地在可用的Region中分配新对象。这个阶段需要停顿线程,但耗时很短,而且是借用进行MinorGC的时候同步完成的,所以G1收集器在这个阶段实际并没有额外的停顿。

  2. 并发标记(Concurrent Marking) :从GC Root开始对堆中对象进行可达性分析,递归扫描整个堆里的对象图,找出要回收的对象,这阶段耗时较长,但可与用户程序并发执行。当对象图扫描完成以后,还要重新处理SATB记录下的在并发时有引用变动的对象。

  3. 最终标记(FinalMarking):对用户线程做另一个短暂的暂停,用于处理并发阶段结束后仍遗留下来的最后那少量的SATB记录。

  4. 筛选回收( Live Data Counting and Evacuation) :负责更新Region的统计数据,对各个Region的回收价值和成本进行排序,根据用户所期望的停顿时间来制定回收计划,可以自由选择任意多个Region构成回收集,然后把决定回收的那一部 分Region的存活对象复制到空的Region中,再清理掉整个旧Region的全部空间。这里的操作涉及存活对象的移动,是必须暂停用户线程,由多条收集器线程并行完成的。


整体看:标记-清除

局部看:标记-复制

标记阶段并发:原始快照

  • 20
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值