经典垃圾收集器概览

一、新生代收集器

1、Serial收集器

工作流程

Serial收集器是最基础、历史最悠久的收集器,它在进行垃圾收集时,必须暂停其他所有工作线程,然后使用一条收集线程去完成收集工作,直到收集结束,其他工作线程再恢复。

优点

Serial收集器的优点是简单高效、额外内存消耗小

缺点

Serial收集器中暂停所有工作线程的操作被称为Stop The World,由虚拟机在后台自动发起和自动完成,这种在用户不可知、不可控的情况下把用户的正常工作线程的线程全部停掉的操作通常对很多应用来说都是不可接受的。因为如果停顿时间过长,应用服务体验就会降低。

适用场景

Serial收集器适用于内存资源有限、处理器核心数较少的环境中,因为Serial收集器由于没有线程交互的开销,专心做垃圾收集自然可用获得最高的单线程收集效率。
Serial收集器目前仍然是HotSpot虚拟机运行在客户端模式下的默认收集器。

2、ParNew收集器

工作流程
ParNew收集器相当于是Serial收集器的多线程并行版本,除了同时使用多条线程进行垃圾收集之外,其余的行为包括Serial收集器可用的所有控制参数、收集算法、对象分配规则和回收策略等都与Serial收集器完全一致。

优点
相对于Serial来说,并行收集减少了用户线程停顿的时间;能够与CMS收集器配合工作。

缺点
仍然会有用户线程停顿

使用场景
与CMS收集器配合工作,有较多核心数的服务器中。

3、Parallel Scavenge收集器

工作流程
Parallel Scavenge收集器的特点是它的关注点与其他收集器不同,CMS收集器的关注的是尽可能的缩短垃圾收集时用户线程停顿时间,但Parallel Scavenge收集器关注的是达到一个可控制的吞吐量,所谓的吞吐量就是处理器用于运行用户代码的时间与处理器总消耗时间的比值,即吞吐量 = 用户代码运行间 / (用户代码运行时间 + 运行垃圾收集时间);

Parallel Scavenge收集器提供了-XX:MaxGCPauseMillis参数控制垃圾收集器最大的停顿时间和-XX:GCTimeRatio参数设置吞吐量的大小。垃圾收集停顿时间缩短是以牺牲新生代空间和吞吐量为代价换取的。

优点
Parallel Scavenge收集器有一个-XX:GCAdaptiveSizePolicy参数,当这个参数被设置激活后,虚拟机会根据当前系统的运行情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或最大的吞吐量。因此如果对于收集器运作不太了解,手工优化存在困难的情况下使用Parallel Scavenge收集器配合自适应调节策略,把内存管理的调优任务交给虚拟机完成也许是一个不错的选择。

二、老年代收集器

1、Serial Old收集器

Serial Old是Serial收集器的老年代版本,它同样是一个单线收集器,这个收集器的主要意义是提供给客户端模式下的HotSpot虚拟机对老年代的收集使用。

2、Parallel Old收集器

Parallel Old是Parallel Scavenge收集器的老年代版本,支持多线程并发收集。在注重吞吐量或者处理器资源较为稀缺的场合,都可以优先考虑Parallel Scavenge 加Parallel Old收集器这个组合。

3、CMS收集器

CMS(Concurrent Mark Sweep,并发标记清除)收集器是一种以获取最短回收停顿时间为目标的收集器。

工作流程
CMS相对于前述几种收集器的运作过程相对更加复杂,整个过程分为四个步骤:

  • 初始标记
    标记GC Roots能直接关联到的对象,速度很快。
  • 并发标记
    并发标记阶段就是从GC Roots的直接关联对象开始遍历整个对象图的过程,这个过程耗时较长但是不需要停顿用户线程,可以与垃圾收集线程一起并发运行。
  • 重新标记
    重新标记则是为了修正并发标记期间,因用户线程运作而导致标记产生变动的那一部分对象的标记记录。
  • 并发清除
    清除删除掉标记阶段判断的已死亡的对象,这个阶段也是可以与用户线程同时并发的。

其中初始标记、重新标记这两个步骤仍然需要Stop The World,重新标记阶段的停顿时间通常会比初始标记阶段稍长一些,但也远比并发标记阶段的时间短。所以整个过程中并发标记和并发清除是耗时最长的。

优点
尽可能的减少了收集停顿时间

缺点
其一,CMS收集器对处理器资源非常敏感,CMS在并发标记和并发清除阶段虽然不会导致用户线程停顿,但也会因为占用了一部分线程而导致应用程序变慢,降低总吞吐量。CMS默认启动的回收线程数是(处理器核心数量 + 3)/ 4,因此核心数越少的服务器,CMS对用户程序的影响就越大。
其二,由于CMS收集器无法处理“浮动垃圾”,有可能出现“Concurrent Mode Failure”失败而导致另一次完全的Stop The World的Full GC产生。浮动垃圾是指那些在并发标记和并发清除阶段,用户线程仍然运行中产生的已死对象,由于这一部分已死对象是在标记过程结束以后产生的,CMS无法在此次回收中处理它们,留在下一次处理,这部分垃圾就被称为浮动垃圾。
其三,由于垃圾收集阶段用户线程仍然运行,因此需要预留足够的内存空间提供给用户线程使用,所以CMS收集器不能像其他收集器那样等到老年代快被填满了才进行收集,必须预留一部分空间供并发收集时的程序运作使用。
其四,CMS是基于标记清除算法实现的垃圾收集器,回收时会产生一定的空间碎片。

使用场景
适用于希望停顿时间较短的服务的应用。

三、混合垃圾收集器

1、G1(Garbage First)收集器

设计目标
G1收集器是一款主要面向服务端应用的垃圾收集器,开创了收集器面向局部收集的设计思路和基于Region的内存布局形式。G1的设计目标是能够支持在指定一个M毫秒的时间片段内,消耗在垃圾收集上的时间大概率不超过N毫秒。G1的默认停顿目标时间为200毫秒。
在G1收集器之前的收集器的收集目标要么是新生代,要么是老年代,或者整个Java堆,而G1面向的是堆内存任何部分来组成的回收集进行回收,衡量标准不在是某一个分代,而是哪块内存中存放的垃圾数量最多,回收收益最大。
从G1开始,最先进的垃圾收集器的设计导向都是垃圾回收的速度能够跟上用户应用程序内存分配的速度,只要满足了这个条件,应用程序就能完美正常运行。

实现思路
G1开创的基于Region的堆内存布局是它能够实现这个目标的关键,虽然G1仍然是基于分代收集理论设计的,但G1不是固定大小以及固定数量的分代区域划分,而是把连续的Java堆划分为多个大小相等的独立区域Region,每一个Region都可以根据需要,扮演新生代的Eden空间、Survivor空间或者老年代空间。收集器能够对扮演不同角色的Region采用不同的策略去处理。

Region中还有一类特殊的Humongous区域,专门用来存储大对象,G1中只要超过了一个Region容量一半的对象就判定为大对象,每个Region的大小可以通过-XX:G1HeapRegionSize设定,取值范围为1MB ~ 32MB,且应为2的N次幂。而对于那些超过了一个Region容量的超大对象,则会被存放在N个连续的Humongous Region。

如何保证尽可能高的收集效率
G1收集器会去跟踪各个Region里面的垃圾堆积的价值大小,所谓价值即回收所获得的空间大小以及回收所需时间的经验值,然后会在后台维护一个优先级列表,每次根据用户设定允许的收集停顿时间,优先处理回收价值收益最大的那些Region,这也是Garbage First名字的由来。

运作过程

  • 初始标记: 仅标记GC Roots能直接关联到的对象,并且修改TAMS指针的值(TAMS,即Top at Mark Start,G1为每一个Region设计了两个名为TAMS的指针,把Region中的一部分空间划分出来用于并发回收过程中的新对象分配,并发回收时新分配的对象地址都必须要在这两个指针位置以上,并且不纳入回收范围)。这个阶段需要停顿线程,但耗时很短。
  • 并发标记:从GC Roots开始对堆中对象进行可达性分析,递归扫描整个堆里的对象图,找出要回收的对象,改阶段耗时较长,但可与用户程序并发执行。
  • 最终标记:对用户线程做另一个短暂的暂停,用于处理并发阶段结束后仍遗留下来的最后少量的SATB记录。(SATB,即Snapshot At The Beginning,即开始时的存储快照)。
  • 筛选回收:负责对各个Region的回收价值和成本进行排序,根据用户所期望的停顿时间来制定回收计划,可用自由选择多个Region构成回收集,然后把决定回收的那一部分Region的存活对象复制到空的Region中,再清理掉旧Region的全部空间。改阶段会暂停用户线程,由多条收集器线程并行完成。

与CMS相比
G1与CMS收集器的运作过程相似,且都非常关注停顿时间的控制。相比CMS,G1的优点有很多,例如可以指定最大停顿时间、分Region的内存布局,与CMS的标记清除算法不同,G1从整体来看是基于标记整理算法实现的收集器,但从局部来看又是基于标记复制算法实现。这意味着G1运作期间不会产生内存空间碎片。不过G1也有其劣势,比如无论是为了垃圾收集产生的内存占用还是程序运行时的额外执行负载都要比CMS要高。
目前在小内存应用上CMS的表现大概率仍然要优于G1,而大内存应用中,G1则大多能发挥更大的优势。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值