Hotspot中各种垃圾收集器
Serial收集器:串行回收
Serial收集器是一个单线程工作的收集器,它在进行垃圾收集时,必须暂停其他所有工作线程,直到它收集结束。虽然其是一个年代比较悠久的收集器,但事实上,迄今为止,它任然是Hotspot虚拟机运行在客户端模式下的默认新生代收集器。对于内存受到限制的环境,它是所有收集器中额外内存消耗最小的;对于单核处理器或处理器核心较少的环境来说,Serial收集器 由于没有线程交互的开销,专心做垃圾收集自然可以获得最高的单线程收集效率。
ParNew收集器:并行回收
ParNew收集器实质上是Serial收集器的多线程并行版本,除了同时使用多线程进行垃圾收集之外,其余的行为包括Serial收集器的所有控制参数,收集算法、Stop the world、对象分配规则、回收策略等都与Serial完全一致。ParNew收集器是激活CMS后的默认新生代是收集器。
Parallel Scavenge 收集器:吞吐量优先
Parallel Scavenge收集器也是一款新生代收集器,它的关注点和其他收集器不一样,CMS等收集器的关注点是尽可能地收缩短垃圾收集时用户线程的停顿时间,而Parallel Scavenge收集器的目标则是到达一个可控制的吞吐量(Throughput)。高吞吐量可以最高效率的利用收集器资源,尽快的完成程序的运算任务,主要适合在后台运算而不需要太多交互的分析任务。
Serial Old收集器
Serial Old是Serial收集器的老年代版本,它同样是一个单线程收集器,使用标记--整理算法。这个收集器的主要意义也是供客户端模式下的Hotspot虚拟机使用。
Serial Old收集器是运行在Client模式下的默认老年代回收器;在Sever模式下主要有两个用途:①与新生代的Parallel Scavenge配合使用;②作为老年代CMS收集器的后备GC方案。
优点;1、简单而高效(与其他单线程收集器比较)
2、运行在Client模式下是个不错的选择。
Parallel Old收集器
Parallel Old收集器是Parallel Scavenge收集器的老年代版本,支持多线程并发收集,基于标记--整理算法实现。在JDK6之前,Parallel Scavenge收集器一直处于非常尴尬的状态,原因是如果新生代选择Parallel Scavenge,而老年代能够选择只有Serial Old收集器。但是由于老年代Serial Old收集器在服务端应用性能上的“拖累”,使用Parallel Scavenge收集器不一定能够在整体上面获得最大吞吐量最大化的效果。 Parallel Old收集器出现很好的改善了这一情况,在注重吞吐量或者处理器资源较为稀缺的场合,都可以优先考虑Parallel Scavenge加Parallel Old收集器的组合。
CMS收集器:低延迟
CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收时间为目标的收集器。目前很大一部分的Java应用集中在互联网或者基于浏览器的B/S系统的服务端上,这类应用通常都较为关注服务的响应速度,希望系统停顿时间尽可能短,以给用户带来良好的交互体验。CMS收集器就非常符合这类应用的需求。CMS是基于标记--清除算法的。
CMS的运行步骤:
1)初始标记(CMS initial mark):该阶段仅仅只是标记一下GC Roots能直接关联到对象, 速度很快。STW
2)并发标记(CMS concurrent mark):该阶段就是从GC Roots的直接关联对象开始遍历整个对象的过程,这个过程虽然耗时比较长但是不需要停顿用户线程,可以和垃圾收集线程一起并发执行。
3)重新标记(CMS remark):该阶段是为了修正并发标记期间,因为用户线程继续运作而导致的标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间通常会比初始标记阶段稍长一些,但也比并发标记的时间短。STW
4)并发清除(CMS concurrent sweep):该阶段清理删除标记阶段判断的已经死亡的对象,由于不需要移动存活对象,所以这个阶段也是可以与用户线程同时并发的。
CMS收集器优点:并发收集、低延迟
缺点:1、会产生内存碎片,因其使用Mark--Sweep算法,导致并发清除后用户线程 可用的空间不足,对象无法分配时会触发Full GC。
2、CMS收集器对cpu资源非常敏感,在并发阶段,它虽然不会导致用户停顿 但是会因为占用了部分线程而导致应用程序编码,总吞吐量降低。为了解 决这个问题虚拟机提供了一种称为“增量式并发收集器”的CMS收集器变 种,所做的事情和以前单核处理器年代PC即操作系统靠抢占式多任务来 模拟多核并行多任务的思想一样,是在并发标记、清理的时候让收集器线 程、用户线程交替运行。尽可能地减少垃圾收集线程的独占资源的时间, 这样整 个垃圾收集的过程会更长,但是对用用户程序的影响就会显得较少 一点。
3、无法处理“浮动垃圾”。
Garbage First收集器:区域分代化
Garbage First(简称G1)收集器是垃圾收集器技术发展史上里程碑的成果,开创了收集器面向局部收集的设计思路和基于Region的内存布局形式。G1是一款主要面向服务端应用的垃圾收集器,主要针对配备多核cpu以及大容量内存的机器。
其他所有垃圾收集器,包括CMS在内的垃圾收集目的范围要么是整个新生代(Minor GC),要么是整个老年代(Major GC),在要么就是整个java堆(Full GC)。而G1和他们都不同,它面向堆内存任何部分来组成回收集(Collection Set,一般简称CSet)进行回收,衡量标准不再是它时属于哪个分代,而是那块内存中存放的垃圾数量最多,回收效益最大,这就是G1收集器的Mixed GC模式。
G1收集器虽然也是遵循分代收集理论设计的,但其堆内存的布局与其他收集器有着非常明显的差异。G1不再坚持固定大小以及固定数量的分代区域划分,而是把连续的java对划分为多个大小相等的独立区域(Region),每个Region都可以根据需要,扮演新生代的Eden空间、Survior空间、或者老年代区域。
G1收集器对于垃圾的具体收集思路是跟踪各个Region里面的垃圾堆积的“价值”大小,价值即回收所需的空间大小以及回收所需要时间的经验值,然后在后台维护一个优先级列表,每次根据用户设定允许的收集停顿时间,优先处理回收价值收益最大那些Region,这也是"Garbage First"名字的由来。这种使用Region划分内存空间,以及具有优先级的区域回收方式,保证了G1收集器在有限的时间内获取尽可能高的收集效率。
G1处理过程
1)初始标记:仅仅是标记GC Roots能直接关联的对象,速度很快。stop the word。
2)并发标记:从GC Roots开始对堆中对象进行可达性分析,递归扫描整个堆里面的对象图,找出要回收的对象,这阶段耗时长,但可与用户程序并发执行。
3)最终标记:对用户线程另一个短暂的暂停,用于处理并发阶段结束后人遗留下来的那最后少量的SATB记录,即修正在并发标记阶段因为用户线程继续运行而导致标记记录产生变动的那一部分对象的标记记录。stop the word。
4)筛选标记:负责更新Region的统计数据,对各个Region的回收价值和成本进行排序,根据用户所期望的停顿时间制定回收计划。这阶段停顿用户线程。stop the word。
G1收集器的优劣势:
优势如下:
与其他GC收集器相比,G1使用了全新的分区算法。
并行与并发:
并行性:G1回收期间,可以有对个GC线程同时工作,有效利用多核计算能力,此时用户线程STW。
并发性:G1拥有与应用程序交替执行的能力,部分工作可以和应用程序同时执行,因此,一般来说,不会再整个回收阶段发生完全阻塞应用进程的情况。
分代收集:
①从分代上来看,G1依然属于分代型垃圾回收期,但是从堆结构上来看,它不要求整个Eden区,年轻代或者老年代都是连续的,也不再坚持固定大小和固定数量。
②将堆空间分为若干区域(Region),这些区域包含逻辑上的年轻代和老年代。
③与其他几种经典的垃圾回收器不同,它兼顾了年轻代和老年代。
空间整合:
CMS:使用“Mark--Sweep”算法、会有内存碎片、进行若干次GC后进行一次碎片整理。
G1:将内存划分为一个各个的Region,内存回收以Region作为基本单位。Region之间使用复制算法(如从Eden区复制到Survivor区),但整体上实际可看做标记--压缩算法。两种算法都可以避免内存碎片,因此有利于程序长时间运行,分配大对象是不会因为无法找到连续内存空间而提前触发下一次GC,尤其当堆非常大时,G1优势更明显。
可预测的停顿时间模型:
每次根据允许的收集时间,优先回收价值最大的Region,保证了G1收集器在有限的时间内可以获取尽可能高的收集效率。
劣势如下:
G1无论是为了垃圾收集产生的内存占用还是程序运行时的额外负载都要比CMS要高。CMS在小内存的表现大概率会优于G1,反之,则G1优。
G1收集器的适用场景:
①面向服务端应用,针对具有大内存、多处理器的机器
②最主要的应用是为需要低延迟、并具有大堆的应用程序提供解决方案
③用来替换JDK1.5的CMS收集器
G1可能优于CMS情况:
1)超过50%的Java堆被活动数据占据
2)GC停顿时间过长
3)对象分配或年代提升频率变化很大。
Serial GC、Parallel GC、Concurrent Mark Sweep GC有什么不同呢?
①若想要最小化地使用内存和并行开销,选择Serial GC。
②若想要最大化应用程序的吞吐量,选择Parallel GC。
③若想要最小化GC的中断或者停顿时间,选择CMS。
为何CMS不可与Parallel Scavenge GC搭配?
Parallel底层使用框架与其他收集器不同,故CMS不与Parallel兼容
不同年代对并行和串行方式选择
对于新生代,回收次数频繁,使用并发方式效率高。
对于老年代,回收次数较少,使用串行方式节省资源。
7种经典垃圾收集器比较
串行:Serial 、Serial Old
并行:ParNew 、Parallel Scavenge 、Parallel Old
并发:CMS、G1