G1收集器和CSM收集器对比

来源:互联网 发布:对高维数据进行降维 编辑:程序博客网 时间:2024/06/05 04:50

(http://blog.csdn.net/zhanggang807/article/details/45956325)

回顾分代垃圾回收和CMS

并发标记清除(CMS)收集器(也叫并发低延迟收集器)回收年老代垃圾。它通过和应用线程并发的执行大部分垃圾收集工作的方式来尝试最小化垃圾回收引起的暂停。正常情况下并发低延迟收集器不会复制或者压缩活跃对象。一次垃圾收集的完成不必移动活跃对象。如果内存碎片成为一个问题,分配更大的堆空间。

注意: CMS收集器在年轻代上使用和并行收集器相同的算法。

CMS收集阶段

CMS收集器在堆的年老代空间上执行以下阶段:

阶段描述(1)初始标记(Stop the World事件)年老代里的对象被标记为可达的包括那些可能从年轻代可达的对象。此期间暂停时间相对minor gc的暂停时间是比较 短的(2)并发标记当Java应用线程运行时,并发的遍历年老代对象图可达的对象。从标记的对象和根上可达到标记对象开始扫描。设值方法在并发的2、3、5阶段期间执行,在这些阶段(包括晋升的对象)被分配进CMS代所有对象都会立刻被标记为活跃对象。(3)重新标记(Stop the World事件)寻找那些在并发标记阶段丢失的,在并发收集器完成之后跟踪对象之后由Java应用线程的更新的对象。(4)(并发清除)收集在标记阶段被鉴定为不可达的对象。收集死亡对象会增加空闲列表的空间,方便之后的对象分配。聚合死亡对象可以会在此点发生。注意活跃对象是不会被移动。(5)(重新设置)清理数据结构为下一次并发收集做准备

回顾垃圾收集步骤

接下来,让我们一步一步的回顾下CMS收集器的操作步骤

1. CMS收集器堆结构

堆空间被分割为三块空间。 
CMS Heap Structure
年轻代分割成一个Eden区和两个Survivor区。年老代一个连续的空间。就地完成对象收集。除非有FullGC否则不会压缩。

2.CMS年轻代垃圾收集如何工作

年轻代被标为浅绿色,年老代被标记为蓝色。如果你的应用已经运行了一段时间,CMS的堆看起来应该是这个样子。对象分散在年老代区域里。 
How Young GC Works
使用CMS,年老代对象就地释放。它们不会被来回移动。这个空间不会被压缩除非发生FullGC。

3.年轻代收集

从Eden和Survivor区复制活跃对象到另一个Survivor区。所有达到他们的年龄阈值的对象会晋升到年老代。 
Young Generation Collection

4.年轻代回收之后

一次年轻代垃圾收集之后,Eden区和其中一个Survivor区被清空。 
After Young GC
最近晋升的对象以深蓝色显示在上图中,绿色的对象是年轻代幸免的还没有晋升到老年代对象。

5.CMS的年老代收集

发生两次stop the world事件:初始标记和重新标记。当年老代达到特定的占用比例时,CMS开始执行。 
Old gen collection in CMS
(1)初始标记是一个短暂暂停的、可达对象被标记的阶段。(2)并发标记寻找活跃对象在应用连续执行时。最后,在(3)重新标记阶段,寻找在之前并发标记阶段中丢失的对象。

6.年老代收集-并发清除

在之前阶段没有被标记的对象会被就地释放。不进行压缩操作。 
Old Gen Collection - Concurrent Sweep
注意:未被标记的对象等于死亡对象

7.年老代收集-清除之后

(4)清除阶段之后,你可以看到大量内存被释放。你还可以注意到没有进行压缩操作。 
Olg Gen Collection - After Sweeping
最后,CMS收集器会走过(5)重新设置阶段,等待下一次垃圾收集时机的到来。

循序渐进G1垃圾收集器


循序渐进G1垃圾收集器

G1收集器在分配堆空间的方法上有些不同。下面的图片一步一步系统的回顾G1收集器。

1.G1堆结构

堆空间是一个被分成许多固定大小区域的内存块。 
G1 Heap Structure
Java虚拟机启动时选定区域大小。Java虚拟机通常会指定2000个左右的大小相等、每个大小范围在1到32M的区域。

2.G1堆空间分配

实际上,这些区域被映射成Eden、Survivor、年老代空间的逻辑表述形式。 
G1 Heap Allocation
图片中的颜色表明了哪个区域被关联上什么角色。活跃对象从一个区域疏散(复制、移动)到另一个区域。区域被设计为并行的方式收集,可以暂停或者不暂停所有的其它用户线程。

明显的区域可以被分配成Eden、Survivor、Old区域。另外,有第四种类型的区域叫做极大区域(Humongous regions)。这些区域被设计成保持标准区域大小的50%或者更大的对象。它们被保存在一个连续的区域集合里。最后,最后一个类型的区域就是堆空间里没有使用的区域。

注意:写作此文章时,收集极大对象时还没有被优化。因此,你应该避免创建这个大小的对象。

3.G1的年轻代

堆空间被分割成大约2000个区域。最小1M,最大32M,蓝色区域保持年老代对象,绿色区域保持年轻代对象。 
Young Generation in G1
注意:区域没有必要像旧的收集器一样是保持连续的。

4.G1的年轻代收集

活跃对象会被疏散(复制、移动)到一个或多个survivor区域。如果达到晋升总阈值,对象会晋升到年老代区域。 
A Young GC in G1
这是一个stop the world暂停。为下一次年轻代垃圾回收计算Eden和Survivor的大小。保留审计信息有助于计算大小。类似目标暂停时间的事情会被考虑在内。

这个方法使重调区域大小变得很容易,按需把它们调大或调小。

5.G1年轻代回收的尾声

活跃对象被疏散到Survivor或者年老代区域。 
End of Young GC with G1
最近晋升的对象显示为深蓝色。Survivor区域显示为绿色。

关于G1的年轻代回收做以下总结:

  • 堆空间是一块单独的内存空间被分割成多个区域。
  • 年轻代内存是由一组非连续的区域组成。这使得需要重调大小变得容易。
  • 年轻代垃圾回收是stop the world事件,所有应用线程都会因此操作暂停。
  • 年轻代垃圾收集使用多线程并行回收。
  • 活跃对象被复制到新的Survivor区或者年老代区域。

G1年老代垃圾回收

类似CMS收集器,G1收集器为年老代对象被设计成一个低暂停收集器。下面的表描述了在年老代上的G1收集阶段。 
G1垃圾收集器在堆上的年老代执行以下阶段。注意一些阶段是年轻代回收的一部分。

阶段描述(1)初始标记(stop the world事件)这是一个stop the world事件,使用G1回收器,背负着一个常规的年轻代收集。标记那些有引用到年老代的对象的survivor区(根区)(2)根区扫描为到年老代的引用扫描survivor区,这个发生在应用继续运行时。这个阶段在年轻代收集前必须完成(3)并发标记遍历整个堆寻找活跃对象,这个发生在应用运行时,这个阶段可以被年轻代垃圾回收打断。(4)重新标记(stop the world事件)完全标记堆中的活跃对象,使用一个叫作snapshot-at-the-beginning(SATB)的比CMS收集器的更快的算法(5)清理(stop the world事件和并发)在活跃对象上执行审计操作和释放区域空间(stop the world);净化已记忆集合(stop the world);重置空间区域和返回它们到空闲列表(并发)(*)复制(stop the world事件)这些是stop the world暂停为了疏散或者复制活跃对象到新的未使用的区域。这个可以由被记录为[GC Pause (young)]的年轻代区域或者被记录为[GC Pause (mixed)]年轻代和年老代区域完成

循序渐进G1年老代垃圾回收

记住已被定义的阶段,让我们来看一下G1收集器是如何作用于年老代的。

6.初始标记阶段

年轻代垃圾收集肩负着活跃对象初始标记的任务。在日志文件中被标为GC pause (young)(inital-mark) 
Initial Marking Phase

7.并发标记阶段

如果发现空区域(“X”标示的),在重新标记阶段它们会被马上清除掉。当然,决定活性的审计信息也在此时被计算。 
Concurrent Marking Phase

8.重新标记阶段

空的区域被清除和回收掉。所有区域的活性在此时计算。 
Remark Phase

9.复制/清理阶段

G1选择活性最低的区域,这些区域能够以最快的速度回收。然后这些区域会在年轻代垃圾回收过程中被回收。在日志中被指示为[GC pause (mixed)]。所以年轻代和年老代在同一时间被回收。 
Coping/Cleanup Phase

10.复制/清理阶段之后

被选择的区域已经被回收和压缩到图中显示的深蓝色区和深绿色区中。 
After Coping/Cleanup Phase

年老代垃圾回收总结

总结下,我们可以列出一些关于G1收集器在年老代的上关键点。 
并发标记阶段

  • 当应用运行时,并发的计算活性信
  • 在疏散暂停期间,活性信息鉴定哪些区被最好的回收
  • 没有像CMS一样的清除操作

重新标记阶段

  • 使用比在CMS中使用的算法更快的Snapshot-at-the-Beginning(SATB)算法
  • 完全空的区域会被回收掉

复制/清理阶段

  • 年轻代和年老代被同时回收
  • 年老代区域基于它们的活性被选择

0 0
原创粉丝点击