Our Collectors

(2008年2月1日。翻译自https://blogs.oracle.com/jonthecollector/our-collectors。文章比较早,主要对比了ParNew和Paraller Scavenge之间的不同和相同点)
    前段时间,我在给朋友讲解的时候,在白板上画了下面这个图。他们看起来(也许只是表现得)很喜欢,因此我想再给你们画一次。

    每一个蓝色的盒子代表了一种用来分代回收的算法。在黄色区域中代表的是新生代被各种蓝色盒子代表的算法回收,下面的灰色区域中则是老年代被各种盒子代表的算法回收。
    “Serial”是一种需要STW的复制回收算法,它使用的是单线程回收。
    “ParNew”也是一种需要STW的复制回收算法,但是它使用多线程进行回收。它与”Parallel Scavenge”不同的地方在于,为了能让它和CMS适用,它做了一些增强。例如,它做了一些必要的同步以便在CMS的并发回收的时候,它也能运行。
    “Paraller Scavenge”也是一个需要STW的多线程的复制算法。
    “Serial Old”是一个需要STW的标记整理算法,它使用的是单线程。
    “CMS”是一个在大多数时候并发,停顿时间低的回收器。
    “Parallel Old”是一个标记整理回收器,使用的是多线程。

在jdk6中,使用-XX参数来管理我们的回收器。

    使用SerialGC是用”Serial”+”Serial Old”
    使用ParNewGC是用“ParNew”+”Serial Old”
    使用CMS是用“ParNew”+”CMS”+”Serial Old”.在大多数情况下,都使用CMS来回收老年代。“Serial Old”则是在当发生一个concurrent mode failure的时候用的。
    使用ParallelGC是“Paraller Scavenge”+”Serial Old”
    使用ParallelOldGC是“Parallel Scavenge”+”Paraller Old”

    FAQ

    (1)使用ParNew 和ParallerGC都是使用多线程回收新生代,哪个更快?
    答:这个问题没有正确答案。在大多数情况下,他们都表现的不错。但是在不同的场景下其中一个回收器会比另外一个更好。如果你想使用GC ergonomics(堆各分代大小动态调整),那只能用ParallelGC(和ParallelOldGC)。
    (2)为什么“ParNew”和“Parallel Old”不能一起使用?
    答:“ParNew”是在一个框架的基础上写的,在这个框架中,每一个即将被回收的分代都为回收提供了确定的接口。例如,“ParNew”和“Serial”实现了space_iterate()接口。这个接口为这个新生代中的每一个对象都添加了一个方法。当用CMS或者是Serail Old来回收老年代的时候,GC可以使用space_iterate()来为这些在新生代中的对象做一些工作。这使得回收器的混合-匹配起作用,但是为了维持回收器和增加新的回收器增加了负担。而且这个负担看起来是回收器数量的2次方。
    另外,“Parallel Scavenge”(至少在Parallel Old之前的最开始的实现中)总是知道老年代是怎样被收集的,而且可以直接调用Serail Old回收器中的代码。
    顺便提一句,我们想要将Parallel Scavenge和Parallel Old搭配使用,而且会清理任何Paraller Scavenge需要的代码,以便2者能够同时使用。
    不需要对上面我提到的例子思考太多。他们不值得你浪费时间。

    (3)我怎么使用CMS和Serial?
    -XX:+UseConcMarkSweepGC -XX:-UseParNewGC.
    不要使用-XX:+UseConcMarkSweepGC和-xx:+UseSerialGC.虽然他们看起来是一个逻辑组合,但是这会导致回收器冲突,JVM无法启动。
    (4)图上”?”的蓝色盒子是一个输入错误?
    它代表了我们正在开发的一种新的垃圾回收类型,我们称为G1.G1会提供:
    1.更加可预测的GC暂停。
    2.更好的GC自适应调整
    3.更低的暂停且没有内存碎片
    4.并行和并发的回收
    5.更好的堆利用率
    G1对新生代和老年代没有明显的界限,因为它只是逻辑上的分代回收。G1把堆分成一个个区域,然后在一次回收过程中,可以回收区域的一个子集。说它是逻辑上的分代,是因为它会动态的选择区域的一个集合作为一个新生代一样在下次被回收(就像新生代一样)。用户可以设置暂停时间的目标,然后G1会基于过去的回收做一个分析,看多少区域可以在这个暂停时间内回收。这些区域成为一个垃圾集合,G1会在下次进行回收。
    G1可以选择首先对垃圾最多的区域进行回收(知道为什么叫garbage first了没?)
    堆不会静态的被分割为一个新生代和一个老年代,所以他们之间容量大小的平衡在这里不是个问题。
    除了设置停顿时间外,还可以设置在某一个阶段中消耗的GC时间(比如设置在接下来的100秒中垃圾回收时间小于10秒)。为了达到这样的目标,G1可以选择一个回收器能花费小于10s就能回收完成的垃圾集合,从之前的回收中提前计划好90s的时间。
    你可以看到在下一个时代中一个用户可以设置0秒的回收时间,这还只是目标而已,不是承诺。

    如果G1运行的符合我们的期望,它会代替ParNew+CMS而成为我们的低停顿的回收器。如果你想问它什么时候会开发完成,请不要为我死后的沉默冒犯。这个是我们团队最高优的项目,但是这是软件开发,所以常常会有一些未知的因素。它会在jdk7中推出。就我们而言,越早越好。

    2月4号更新。我已经可以重新编辑已经发布的博客,如果你有ACM门户的访问权限,这里是一篇G1论文的链接。
    http://portal.acm.org/citation.cfm?id=1029879

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值