垃圾收集器

本文只是以HotSpot虚拟机为例。

1、Serial收集器:新生代、单线程、复制算法。

       该收集器在执行的过程中,只会使用一个CPU或者一条收集线程去完成垃圾收集工作,并且会暂停其他所有的工作线程,直到它收集结束。虽然如此,但是,它简单而高效,对于限定单个CPU的环境来说,不会产生由于线程切换而引起的开销(从这一点也可以看出,多线程未必比单线程快)。

2、ParNew收集器:新生代、多线程、复制算法。

      默认开启的收集线程数与CPU的数量相同。该收集器在单个CPU中绝对不会比Serial收集器效率高。在这里介绍两个名词:

      并行:指多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态。

      并发:指用户线程与垃圾收集线程同时执行,不一定是并行的,可能会交替执行。

3、Parallel Scavenge收集器:新生代、多线程、复制算法。

      该收集器的目标是达到一个可控制的吞吐量。吞吐量就是CPU用于运行用户代码的时间与CPU总消耗时间的比值,即吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)。这里提供了两个参数用于精确控制吞吐量,即-XX:MaxGCPauseMillis,控制最大垃圾收集停顿时间;-XX:GCTimeRatio,设置吞吐量大小。

      如果把MaxGCPauseMillis设置的小一些,的确能够把系统垃圾收集速度变快,但是垃圾收集发生的会更加频繁一些。停顿时间在下降,但是吞吐量也降下来了。GC停顿时间缩短是以牺牲吞吐量和新生代空间来换取的。所以这个参数并不是设置的越小越好。

     另外,提供了-XX:UseAdaptiveSizePolicy这个参数。当设置了这个参数之后,就不需要我们手动指定新生代的大小(-Xmn)、Eden与Survivor区的比例(-XX:SurvivorRatio)、晋升到老年代对象的年龄(-XX:PretenureSizeThreshold)等这些参数了,虚拟机会根据当前系统的运行情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或最大吞吐量,这种方式称为GC自适应的调节策略。这也是Parallel Scavenge收集器和ParNew收集器的一个重要区别。

4、Serial Old收集器:老年代、单线程、标记-整理算法。

5、Parallel Old收集器:老年代、多线程、标记-整理算法。

     在注重吞吐量和CPU的情况下,可以优先考虑Parallel Scavenge+Parallel Old组合。

6、CMS收集器:老年代、多线程、标记--清除算法。

     主要目标是获取最短回收停顿时间。----并发收集,低停顿

     分为四个阶段:

     a、初始标记:标记GC Roots能直接关联的对象

     b、并发标记:GC Roots Tracing

     c、重新标记:为了修正在并发标记期间,因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录,停顿时间比初始标记长,比并发标记短。

     d、并发清除

     缺点:

     a、对CPU资源敏感。默认启动的回收线程数是(CPU数量+3)/4,即当CPU在4个以上时,并发回收是垃圾收集线程最多占用不超过25%的CPU资源。而当CPU不足4个时,对用户线程的影响就会变得很大。

     b、无法处理浮动垃圾。在CMS并发清理阶段,用户线程会在运行着,那自然还会有新的垃圾不断产生,这一部分垃圾出现在标记过程之后,CMS无法再本次收集中处理掉它们,只好待下一次GC时再将它们清理掉。这就是所谓的浮动垃圾。

     c、会产生大量的碎片

7、G1收集器:新生代和老年代、多线程、标记--整理算法。

     G1收集器将整个Java堆划分为多个大小不等的独立区域(Region),虽然有新生代和老年代的概念,但是他们已经不在是物理隔离了,而是一部分不需要连续的集合。

     主要特点有:

     a、并行与并发:G1能充分利用硬件资源以并行的方式来缩短停顿时间,并通过并发的方式让java程序继续执行。

     b、分代收集:不需要与其他收集器配合使用,就可以独立管理整个GC堆。

     c、空间整合:G1整体基于”标记--整理“算法,局部采用”复制“算法,这都不会产生碎片。

     d、可预测的停顿:可以非常精确的控制停顿时间,能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在垃圾上的时间不超过N毫秒。能够做到这一点的原因是因   为它可以有计划避免在真个Java堆中进行全区域的垃圾收集。G1跟踪各个区域里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需时间的经验值),在后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的区域。 

     G1是如何做到不进行全区域扫描的呢?

     G1中每个Region都有一个与之对应的Remembered Set,虚拟机发现程序在对引用类型的数据进行写操作时,会产生一个中断写操作,检查引用的对象是否处于不同的区域 之中,如果是,便把相关信息记录到被引用对象所属的区域的Remembered Set中。当进行内存回收时,在GC根节点的枚举范围中加入Remembered Set即可保证不对全区域扫描也不会有遗漏。

     G1收集器分为以下几个步骤:

     a、初始标记:标记以下GC Roots能直接关联到的对象,并且修改TAMS(Next  Top at  Mark Start)的值,让下一阶段用户程序并发运行时,能在正确可用的区域中创建新对象,这里需要短时间的停顿线程。

     b、并发标记:从GC Roots开始对堆中对象进行可达性分析,找到存活的对象,耗时较长,但可与用户线程并发执行。

     c、最终标记:为了修正在并发标记期间因用户线程继续执行而道正标记产生变动的那一部分变动记录,虚拟机将这段时间对象变化记录在线程Remembered Set Logs里面,该阶段需要把Remembered Set Logs的数据合并到Remembered Set中,这个阶段需要停顿线程,但是可并行执行。

     d、筛选回收:对各个Region的回收价值和成本进行排序,根据用户所期望的GC停顿时间来制定回收计划。   



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值