原文連接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本文連接地址: 咱們的垃圾收集器