Java虚拟机-垃圾收集器

垃圾收集器可以分为新生代收集器和老年代收集器;

新生代收集器:

1、  Serial收集器

Serial收集器是单线程收集器,采用复制算法,并行收集器,执行的时候需要用户线程暂停。

虚拟机运行在Client模式下的默认新生代收集器。

2、  ParNew收集器

ParNew收集器是多线程收集器,采用复制算法,并行收集器,执行的时候需要用户线程暂停。

除了Serial收集器可以和CMS收集器搭配使用之外,就是ParNew收集器;

3、  Parallel Scavenge收集器

Parallel Scavenge收集器是多线程收集器,采用复制算法,并行收集器,执行的时候需要用户线程暂停。

此收集器主要注重的是可控制的吞吐量;

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

老年代收集器:

1、  Serial Old收集器

Serial Old收集器是单线程收集器,采用标记-整理算法,并行收集器,执行的时候需要用户线程暂停。

Sweep清理和Compact压缩:

清理就是把废弃的对象干掉,只留下幸存的对象;

压缩就是将移动对象,将空间填满保证内存分为2块,一块是全是对象,一块空闲

2、  Parallel Old收集器

Parallel Old收集器是多线程收集器,采用标记-整理算法,并行收集器,执行的时候需要用户线程暂停。

JDK1.6才开始提供此收集器。

Summary汇总和Compact压缩:

汇总是将幸存的对象复制到预先准备的区域

3、  CMS收集器

CMS收集器是多线程收集器,采用标记-清除算法,并发收集器,执行的时候可以和用户线程一起,停顿时间小;

分为四个过程:初始标记、并发标记、重新标记和并发清理

初始标记和重新标记是需要用户线程暂停;

并发标记和并发清理不需要用户线程暂停;

初始标记:标记GC Roots能关联到的对象,停顿时间很短。

并发标记:执行GC Roots查找引用的过程,不需要用户线程停顿。

重新标记:在初始化标记和并发标记期间,有标记变动的那部分仍然需要标记,所以加上这一部分标记过程,停顿时间比并发标记小,但是比初始标记稍微长。

并发清除:在完成标记之后,就开始并发清除,不需要用户线程停顿。

在CMS清理过程中,只有初始标记和重新标记需要停顿用户线程,并发标记和并发清除不需要用户线程停顿,因此效率很高,很适合高交互的场合。

CMS的缺点:

1:对CPU资源比较敏感

它需要消耗额外的CPU和内存资源,在CPU和内存资源紧张的时候,CPU较少时,会加重系统负担;CMS默认启动线程数量:(CPU数量+3)/4

2:CMS收集器无法处理浮动垃圾

CMS收集器在并发收集过程中,用户线程仍然在执行,仍然会产生内存垃圾,所以可能产生浮动垃圾,本次无法清理就只能等待下一次Full GC,因为GC期间需要预留足够内存给用户线程使用,所以使用CMS收集器并不是年老代满了才会执行Full GC,而是在使用了一大半(默认68%,也就是2/3,使用-XX:CMSInitiatingOccupancyFraction来设置)的时候就要进行Full GC,如果用户线程消耗内存不是特别大,可以适当调高参数来降低GC次数,以此提高性能。如果预留的用户线程内存不够,则会触发ConcurrentModeFailure,此时将触发备用方案:使用Serial Old收集器来手机,但是这样停顿时间就会长了,因此-XX:CMSInitiatingOccupancyFraction不能设置的过大。

3:CMS采用标记-清除算法,会产生内存碎片

其他收集器:

1、  G1收集器

G1是一款面向服务端应用的垃圾收集器,在JDK1.7中出现。

G1是采用标记-整理算法。

分为4个步骤:初始标记、并发标记、最终标记、筛选回收;

1:初始标记

标记一下GC Roots能直接关联到的对象,并且修改TAMS 的值,让下一阶段用户程序并发运行时能够正确可用的Region中创建新对象。此操作需要停顿线程,耗时很短。

2:并发标记

从GC Roots开始对堆中对象进行可达性分析,找出存活的对象。耗时比较长,可以与用户线程并发执行;

3:最终标记

为了修正并发标记期间,因用户线程继续执行而导致标记产生变动的那一部分标记记录;

虚拟机将这段时间对象变化记录在线程Remembered Set Logs里面。

最终标记需要将Remembered Set Logs里面的数据合并到Remembered Set中。

此操作需要停顿线程,但是可以并行执行。

4:筛选回收

首先将各个Region的回收价值和成本进行排序,根据用户所期望的GC停顿时间来制定回收计划,回收一部分Region,时间是用户控制的,而且停顿用户线程将大幅度提高收集效率。

G1收集器的优点:

1:并行与并发

G1能够充分利用多CPU、多核环境下的硬件优势,使用多个CPU来缩短停顿的时间,部分其他收集器是需要停顿Java线程执行GC动作,G1收集器仍然可以通过并发的方式让Java线程继续执行;

2:分代收集

G1虽然可以不需要其他收集器配合就能独立管理整个GC堆,但是它能够采用不同的方式处理新创建对象和已经存活了一段时间、熬过多次GC的旧对象以获得更好的手机效果。

3:空间整合

G1从整体上来看是标记-整理算法实现的收集器,从局部上看是基于“复制算法”实现,但是无论如何这两种算法都意味着G1运作期间不会产生内存空间碎片,收集后能够提供规整的可用内存。

这种特性有利于程序的长时间运行,分配大对象时就不会因为无法找到连续内存空间而提前触发下一次Full GC。

4:可预测的停顿

G1除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒,这几乎已经是实时Java(RTSJ)的垃圾收集器的特征。

 

G1收集器将Java堆划分为多个大小相等的独立区域Region。

G1之所以能够建立可预测的停顿时间模型,主要是它有计划得避免了在整个Java堆中进行全区域的垃圾收集。

G1跟踪各个Region里面的垃圾堆积的价值大小,在后台维护一个优先列表,每次根据允许收集时间,优先回收价值最大的Region。

这种使用Region划分空间以及优先级的区域回收方式,保证了G1在有限的时间内可以获取尽可能高的收集效率。

posted @ 2015-05-18 10:41  time-info  阅读(127)  评论(0编辑  收藏  举报