HotSpot虚拟机的垃圾收集器
七种不同的垃圾收集器,连线的两个垃圾收集器表示可以结合使用(3 + 3 + 1)
1、新生代
(1)Serial收集器(标记-复制)
(1)单线程工作:单线程的意义并不仅仅是说明它只会使用一个处理器或一条收集线程去完成垃圾收集工作,更重要的是情调在它进行垃圾回收时,必须暂停其他工作线程,直到它收集结束。 (2)简单高效(与其他收集器的单线程相比):对于内存资源受限的环境,它是所有收集器里额外内存消耗最小的。 (3)对于运行在客户端模式下的虚拟机是一个很好的选择
(2)ParNew收集器(标记-复制)
Serial的多线程并行版本 (1)运行在HotSpot虚拟机服务端模式下。
(3)Paralell Scavenge收集器(标记-复制)
(1)收集目标:达到一个可控制的吞吐量(所谓吞吐量:就是处理器用于运行用户代码的时间与处理器总消耗时间的比值) (2)吞吐量优先垃圾收集器
2、老年代
(1)Serial Old收集器(标记-整理)
单线程收集、供客户端模式下的HotSpot虚拟机使用 如果在服务端有两种用途: 1)在JDK5以及之前的版本何种与Parallel Scavenge收集器搭配使用 2)作为CMS收集器繁盛失败时的后备预案,在并发收集发生Concurrent Mode Failure时使用。
(2)Parallel Old收集器(标记-整理)
多线程并发收集 在注重吞吐量或者处理器资源较为稀缺的场合,都可以优先烤炉Parallel Scavenge 和Parallel Old收集器这个组合
(3)CMS收集器(标记-清除)
CMS收集器是一种以获取最短回收停顿时间为目标的收集器 1、CMS的过程 (1)初始标记 (2)并发标记 (3)重新标记 (4)并发清除 其中初始标记、重新标记这两个步骤仍然需要“ Stop The World”。 (1)初始标记仅仅只是标记一下GC Roots能直接关联到的对象,速度很快; (2)并发标记阶段就是从GC Roots的直接关联对象开始遍历整个对象图的过程,这个过程耗时较长但是不需要停顿用户线程,可以与垃圾收集线程一起并发运行; (3)重新标记阶段则是为了修正并发标记期间,因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录(增量更新),这个阶段的停顿时间通常会比初始标记阶段稍长一些, 但也远比并发标记阶段的时间短: (4)并发清除阶段,清理删除掉标记阶段判断的已经死亡的对象,由于不需要移动存活对象,所以这个阶段也是可以与用户线程同时并发的。
??由于在整个过程中耗时最长的并发标记和并发清除阶段中,垃圾收集器线程都可以与用户线程一起工作, 所以总体上来说,CMS收集器的内存回收过程是与用户线程起并发执行的。
??在并发标记和并发清除阶段产生的浮动垃圾只能等待下一次垃圾回收时才被清理,因此CMS垃圾收集器不能像其他垃圾收集器那样等待到老年代几乎被填满了再进行收集,必须预留一部分空间供并发收集时的程序运作使用。 ??要是CMS运行期间预留的内存无法满足程序分配的新对象的时候,就会出现一次“并发失败”(Concurrent Mode Failure),这个时候虚拟机不得不启动后备预案:冻结用户线程的执行,临时启用Serial Old收集器重新进行老年代的垃圾收集,这样停顿的时间就很长了。 2、CMS的三个明显缺点 (1)CMS收集器对处理器资源非常敏感 (2)CMS收集无法处理浮动垃圾,有可能会出现Concurrent Mode Faliure失败进而导致另一次完全“Stop the Word”的Full GC产生 (3)垃圾收集结束会产生大量的空间碎片。
3、G1垃圾收集器(标记-整理)
宏观上是:标记-整理 微观上是:标记-复制 G1收集器的运作过程大致可划分为以下四个步骤: (1)初始标记( Initial Marking):仅仅只是标记一下GC Roots能直接关联到的对象,并且修改TAMS 指针的值,让下一阶段用户线程并发运行时,能正确地在可用的Region 中分配新对象。这个阶段需要停顿线程,但耗时很短,而且是借用进行Minor GC 的时候同步完成的,所以G1收集器在这个阶段实际并没有额外的停顿。 (2)并发标记( Concurrent Marking):从GC Root开始对堆中对象进行可达性分析,递归扫描整个堆里的对象图,找出要回收的对象,这阶段耗时较长,但可与用户程序并发执行。当对象图扫描完成以后,还要重新处理SATB 记录下的在并发时有引用变动的对象 (3)最终标记( Final Marking):对用户线程做另一个短暂的暂停,用于处理并发阶段结束后仍遗留下来的最后那少量的SATB 记录。 (4)筛选回收( Live Data Counting and Evacuation): 负责更新Region的统计数据,对各个Region的回收价值 和成本 进行排序,根据用户所期望的停顿时间 来制定回收计划,可以自由选择任意多个Region构成回收集,然后把决定回收的那一部分Region的存活对象复制到空的Region中,再清理掉整个旧Region的全部空间。这里的操作涉及存活对象的移动,是必须暂停用户线程, 由多条 收集器线程并行完成的。 垃圾收集过程中产生的问题 (1)在并发阶段如何保证收集线程与用户线程互不干扰的运行,首先解决用户线程改变对象引用关系时,必须保证其不能打破原来的对象图结构。 ??CMS收集器采用增量更新算法实现 ??G1收集器通过原始快照(STAB)算法来实现。 (2)此外,垃圾收集器对用户线程的影响还体现在回收过程中新创建对象的内存分配上,程序要继续运行就肯定会持续有新对象被创建,G1为每一个Region设计了两个名为TAMS(top at mark Start)的指针,把Region中的一部分空间划分出来用于并发回收过程中的新对象分配,并发回收时新分配的对象的地址都必须要在这两个指针位置上。。 (3)与CMS中的“Concurrent Mod Failure” 失败会导致FUll GC类似,如果内存回收的速度赶不上内存分配的速度,G1收集器也要被迫冻结用户线程执行,导致Full GC而产生长时间的stop the world
4、“对象消失”的条件
当且仅当满足以下两个条件同时满足时,会产生“对象消失”的问题 (1)复制器插入了一条或者多条从黑色对象到白色对象的新引用 (2)复制器删除了全部从灰色对象到该白色对象的直接或者间接引用
??因此,我们要解决并发扫描时的对象消失问题,只需破坏这两个条件的任意一个即可。由此分别产生了两种解决方案:增量更新( Incremental Update)和原始快照( Snapshot At The Beginning, SATB)。 ??增量更新要破坏的是第一个条件,当黑色对象插人新的指向白色对象的引用关系时,就将这个新插人的引用记录下来,等并发扫描结束之后,再将这些记录过的引用关系中的黑色对象为根,重新扫描一次。这可以简化理解为,黑色对象一旦新插入了指向白色对象的引用之后,它就变回灰色对象了。 ??原始快照要破坏的是第二个条件,当灰色对象要删除指向白色对象的引用关系时,就将这个要删除的引用记录下来,在并发扫描结束之后,再将这些记录过的引用关系中的灰色对象为根,重新扫描一次。 这也可以简化理解为,无论引用关系删除与否,都会按照刚刚开始扫描那一刻的对象图快照来进行搜索。 ??以上无论是对引用关系记录的插人还是删除,虚拟机的记录操作都是通过写屏障 实现的。在HotSpot虚拟机中,增量更新和原始快照这两种解决方案都有实际应用,譬如,CMS是基于增量更新来做并发标记 的,G1 、Shenandoah 则是用原始快照来实现。
|