原文连接java
(译者注:这篇博文发表在2008年,虽然年代有些久远,可是文中说到的垃圾收集器咱们至今还在使用,做者也谈到了对于G1垃圾收集器的指望。)算法
最近我在白板上给客户化了一个图表,他们彷佛对这个有点兴趣,因此我想我能够重画一遍来给大家消遣。编程
每一个蓝色的盒子都表明了一个收集器,用来收集某一代。黄色区域中的蓝色盒子是用来收集新生代的,灰色区域中的蓝色盒子是用来收集老年代的。tomcat
对于JDK6,可使用-XX来标记咱们的收集器。bash
1.UseParallelGC 和UseParNewGC 都是多线程来收集新生代,哪一个更快?多线程
这个问题没有准确的答案。大部分他们性能至关,可是我仍是见过在不一样的情景下其中一个比另外一个更好。并发
2.为何”ParNew”和”Parallel Old”不能同时运行?oracle
在”ParNew” 的风格下,每一个被收集的代对于它的收集都提供一个肯定的接口,好比说,”ParNew”实现了 space_iterate()方法,这个方法将对新生代中的每一个对象应用一个操做。当使用”CMS” 或”Serial Old” 收集老年代的时候。GC可使用 space_iterate() 来对在新生代中的的对象进行操做。这让收集器能够混合工做,可是会形成收集器维持的一些负担。而且这个负担看起来是收集器的二次方。做为一种选择,”Parallel Scavenge”老是知道老年代是怎么收集的,而且能直接调用在”Serial Old” 收集器中的代码。”Parallel Old”不是”ParNew”风格的,因此不会和”ParNew”匹配。顺便说一下,咱们但愿最终只有”Parallel Scavenge”和”Parallel Old”能够进行匹配。性能
对于我上面的使用的例子,不要想太多。他们就是这样设计的,不要浪费太多时间。spa
3.怎样把”Serial”和”CMS”一块儿使用
使用 -XX:+UseConcMarkSweepGC -XX:-UseParNewGC,而不要使用 -XX:+UseConcMarkSweepGC和 -XX:+UseSerialGC。虽然这样的组合看起来合乎逻辑,可是这会致使一个信息表示收集器之间有冲突,JVM将不会启动。
[root@base embed-tomcat-publicity]# java -jar -Xms20m -Xmx30m -XX:+PrintGCDetails -XX:+UseConcMarkSweepGC -XX:+UseSerialGC frbao-publicity-1.0.0.jar Conflicting collector combinations in option list; please refer to the release notes for the combinations allowed Error: Could not create the Java Virtual Machine. Error: A fatal exception has occurred. Program will exit.
4.上图中蓝色盒子中的问号是否是一个排版错误?
这个盒子表明一个正在开发的新的收集器,叫作Garbage First G1收集器。G1将会提供:
G1跨过了新生代和老年代的范围,由于它是一个只有逻辑区域的分代收集器。G1把堆划分为独立区域,在一次GC中能够收集这片区域的一个子集。它是一个逻辑分代是由于它动态的选择一片区域做为新生代,这片区域将在下一次GC中被回收。
用户能够指定一次停顿的目标,G1将会作一个评估(基于过去的收集),评估有多少个区域在此次停顿(停顿目标) 中能够被收集。这片区域被称之为一个回收集合,G1将在下一次GC中去收集它。
G1能选择有最多垃圾的区域进行收集(因此叫Garbage First)。
G1采用压缩算法因此碎片不是问题。为何是个问题呢?由于部分填满的区域会致使内部的碎片。
Java堆没有被静态的分为一个新生代和老年代,因此他们尺寸的不平衡在这里不是问题。
和指定一次停顿时间一块儿,用户能够指定一部分花费在GC上的时间(好比说在下一次100秒钟不要花费超过10秒钟来进行垃圾收集)。对于这个目标(在100秒内的10秒GC时间),G1能选择一个回收集合,这个集合是G1预测它能在10秒内收集完的区域。有可能看到一个用户在下一次收集中指定0秒的垃圾收集时间,但这只是一个目标,不是一个保证。
若是G1能按咱们期待的那样工做,它将取代 “ParNew” + “CMS”. 成为咱们的低停顿收集器。若是你问何时能够准备好G1,请你不要抱怨个人沉默。这是咱们团队最高优先级的工做,但这是一个软件开发,因此常常会有未知事件。它将在jdk7中推出。对咱们而言,越早越好。(译者注:关于G1的论文发表在2004年,而这篇博客发表在2008年,做者就预料到了不肯定性。确实,直到2012年的JDK7u4,Sun公司才认为G1达到了足够成熟的商用程度,移除了“Experimental”的标识)。
另外做者还贴了G1的论文: http://portal.acm.org/citation.cfm?id=1029879
原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文连接地址: 咱们的垃圾收集器