软件开发架构师

垃圾收集器

java 98 2019-04-20 00:18

转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6535455.html 

 

    Hotspot中用过的垃圾收集器有以下7种:

   

    适用于新生代的有:

    1:Serial 串行收集器

    它是一个单线程的收集器,用它进行垃圾回收时,需要暂停所有其他工作线程直至它收集结束。

    2:ParNew 并行收集器

    ParNew其实就是串行收集器的多线程版本,多个收集线程展开工作,适用于多处理器的环境下,一个CPU一个收集线程。

    3:Parallel Scavenge 并行“吞吐量优先”收集器

    吞吐量=CPU执行用户代码时间/(执行用户代码时间+垃圾回收时间)。高吞吐量可以高效利用CPU时间,尽快完成程序的运算任务。

 

    适用于老年代的有:

    1:Serial Old 串行收集器

    它是一个单线程收集器,采用标记—整理算法。同样,在它工作时需要暂停所有其他工作线程。

    2:Parallel Old 并行“吞吐量优先”收集器

    使用多线程和标记—整理算法。在注重CPU吞吐量以及CPU资源敏感的场合,优先考虑使用 Parallel Scavenge+Parallel Old组合进行垃圾回收。

    3:CMS “最短回收停顿优先”收集器

    基于标记—清除算法的收集器,分为四步:初始标记—并发标记—重新标记—并发清除。

    初始标记:标记GCRoots对象们,只需十分短暂地暂停工作线程;

    并发标记:在工作线程继续工作期间,根据GCRoots对象进行可达性分析、标记,这部分不影响工作线程,是并发执行的;

    重新标记:暂停工作线程,对并发标记出来的对象们进行检查修正;

    并发清除:工作线程继续执行,期间有一清理线程并发地清除死亡对象,不影响工作线程。

    CMS收集器把耗时最长的标记、清理阶段都用并发来实现了,但还是有不足的地方:

    1)并发占用CPU资源:并发标记和清除需要占用一部分CPU资源,导致吞吐量变低。

    2)无法处理“浮动垃圾”:在工作线程继续运行期间会产生新的垃圾,而这些垃圾是没有被标记的,只能放到下一次收集在处理。

    3)产生空间碎片:CMS是基于标记—清除算法的,容易产生空间碎片。

 

    通用的最优秀的收集器——G1收集器:

    G1(Garbage-First)收集器不再只用于新生代、老年代,它把堆划分为多个大小相等的区域,然后跟踪各个区域中垃圾的价值(回收获得的空间大小以及回收所需时间),在后台维护一个优先列表把各个区域按照垃圾的价值排列。每次回收时优先回收价值最大的区域。

    G1收集器工作分4步:初始标记—并发标记—最终标记—筛选回收

    前三步与CMS的初始标记、并发标记、重新标记一样,筛选回收则先对各个区域进行垃圾价值的排序,然后根据用户期望的GC停顿时间来制定回收计划,最后进行回收。

    G1的优点:

    1)并行与并发:在多处理器器的环境下仍然可以并发标记、并发清理。

    2)分代收集:新生代和老年代不再是物理上隔离的内存,而是不同的区域集合罢了。

    3)空间整合:从整体看是基于 标记—整理算法,局部看是基于 赋值算法

    4)可预测停顿:使用者可指定每次垃圾回收时间不超过M毫秒。

 

Serial New收集器是针对新生代的收集器,采用的是复制算法
Parallel New(并行)收集器,新生代采用复制算法,老年代采用标记整理
Parallel Scavenge 并行的吞吐量收集器,针对新生代,采用复制收集算法
Serial Old(串行)收集器,老年代串行,采用标记整理
Parallel Old(并行)收集器,针对老年代,标记整理
CMS收集器,基于标记清理
G1收集器:整体上是基于标记 整理 ,局部采用复制
 
综上:新生代基本采用复制算法,老年代采用标记整理算法。cms采用标记清除。
文章评论