HotSpot VM GC 的種類

原文地址:http://www.cnblogs.com/redcreen/archive/2011/05/04/2037029.html

collector種類      

GC在 HotSpot VM 5.0裏有四種:

incremental (sometimes called train) low pause collector已被廢棄,不在介紹.

類別 serial collector parallel collector
throughput collector )
concurrent collector
(concurrent low pause collector)
介紹

單線程收集器
使用單線程去完成所有的gc工作,沒有線程間的通信,這種方式會相對高效

並行收集器
使用多線程的方式,利用多CUP來提高GC的效率
主要以到達一定的吞吐量爲目標

併發收集器
使用多線程的方式,利用多CUP來提高GC的效率
併發完成大部分工作,使得gc pause短

試用場景 單處理器機器且沒有pause time的要求

適用於科學技術和後臺處理
有中規模/大規模數據集大小的應用且運行在多處理器上,關注吞吐量(throughput)

適合中規模/大規模數據集大小的應用,應用服務器,電信領域
關注response time,而不是throughput

使用 Client模式下默認
可使用
可用-XX:+UseSerialGC強制使用
優點:對server應用沒什麼優點
缺點:慢,不能充分發揮硬件資源

Server模式下默認

--YGC:PS FGC:Parallel MSC

可用-XX:+UseParallelGC或-XX:+UseParallelOldGC強制指定

--ParallelGC代表FGC爲Parallel MSC

--ParallelOldGC代表FGC爲Parallel Compacting

優點:高效

缺點:當heap變大後,造成的暫停時間會變得比較長

可用-XX:+UseConcMarkSweepGC強制指定
優點:
對old進行回收時,對應用造成的暫停時間非常端,適合對latency要求比較高的應用
缺點:
1.內存碎片和浮動垃圾
2.old去的內存分配效率低
3.回收的整個耗時比較長
4.和應用爭搶CPU
內存回收觸發 YGC
eden空間不足
FGC
old空間不足
perm空間不足
顯示調用System.gc() ,包括RMI等的定時觸發
YGC時的悲觀策略
dump live的內存信息時(jmap –dump:live)
      
YGC
eden空間不足
FGC
old空間不足
perm空間不足
顯示調用System.gc() ,包括RMI等的定時觸發
YGC時的悲觀策略--YGC前&YGC後
dump live的內存信息時(jmap –dump:live)
      
YGC
eden空間不足
CMS GC
1.old Gen的使用率大的一定的比率 默認爲92%
2.配置了CMSClassUnloadingEnabled,且Perm Gen的使用達到一定的比率 默認爲92%
3.Hotspot自己根據估計決定是否要觸法
4.在配置了ExplictGCInvokesConcurrent的情況下顯示調用了System.gc.
Full GC(Serial MSC)
promotion failed 或 concurrent Mode Failure時;
內存回收觸發時發生了什麼 YGC
清空eden+from中所有no ref的對象佔用的內存
將eden+from中的所有存活的對象copy到to中
在這個過程中一些對象將晉升到old中:
--to放不下的
--存活次數超過tenuring threshold的
重新計算Tenuring Threshold;
單線程做以上動作
全程暫停應用
FGC
如果配置了CollectGen0First,則先觸發YGC
清空heap中no ref的對象,permgen中已經被卸載的classloader中加載的class的信息
單線程做以上動作
全程暫停應用
YGC
同serial動作基本相同,不同點:
1.多線程處理
2.YGC的最後不僅重新計算Tenuring Threshold,還會重新調整Eden和From的大小
FGC
1.如配置了ScavengeBeforeFullGC(默認),則先觸發YGC(??)
2.MSC:清空heap中的no ref對象,permgen中已經被卸載的classloader中加載的class信息,並進行壓縮
3.Compacting:清空heap中部分no ref的對象,permgen中已經被卸載的classloader中加載的class信息,並進行部分壓縮
多線程做以上動作.


YGC
同serial動作基本相同,不同點:
1.多線程處理
CMSGC:
1.old gen到達比率時只清除old gen中no ref的對象所佔用的空間
2.perm gen到達比率時只清除已被清除的classloader加載的class信息
FGC
同serial
細節參數 可用-XX:+UseSerialGC強制使用
-XX:SurvivorRatio=x,控制eden/s0/s1的大小
-XX:MaxTenuringThreshold,用於控制對象在新生代存活的最大次數
-XX:PretenureSizeThreshold=x,控制超過多大的字節的對象就在old分配.
-XX:SurvivorRatio=x,控制eden/s0/s1的大小
-XX:MaxTenuringThreshold,用於控制對象在新生代存活的最大次數

-XX:UseAdaptiveSizePolicy 去掉YGC後動態調整eden from已經tenuringthreshold的動作

-XX:ParallelGCThreads 設置並行的線程數

-XX:CMSInitiatingOccupancyFraction 設置old gen使用到達多少比率時觸發
-XX:CMSInitiatingPermOccupancyFraction,設置Perm Gen使用到達多少比率時觸發
-XX:+UseCMSInitiatingOccupancyOnly禁止hostspot自行觸發CMS GC

注:

  • throughput collector與concurrent low pause collector的區別是throughput collector只在young area使用使用多線程,而concurrent low pause collector則在tenured generation也使用多線程。
  • 根據官方文檔,他們倆個需要在多CPU的情況下,才能發揮作用。在一個CPU的情況下,會不如默認的serial collector,因爲線程管理需要耗費CPU資源。而在兩個CPU的情況下,也提高不大。只是在更多CPU的情況下,纔會有所提高。當然 concurrent low pause collector有一種模式可以在CPU較少的機器上,提供儘可能少的停頓的模式,見CMS GC Incremental mode
  • 當要使用throughput collector時,在java opt里加上-XX:+UseParallelGC,啓動throughput collector收集。也可加上-XX:ParallelGCThreads=<desired number>來改變線程數。還有兩個參數 -XX:MaxGCPauseMillis=<nnn>和 -XX:GCTimeRatio=<nnn>,MaxGCPauseMillis=<nnn>用來控制最大暫停時間,而-XX: GCTimeRatio可以提高GC說佔CPU的比,以最大話的減小heap。

附註SUN的官方說明: 

1. The throughput collector: this collector uses a parallel version of the young generation collector. It is used if the -XX:+UseParallelGC option is passed on the command line. The tenured generation collector is the same as the serial collector.

2. The concurrent low pause collector: this collector is used if the -Xincgc™ or -XX:+UseConcMarkSweepGC is passed on the command line. The concurrent collector is used to collect the tenured generation and does most of the collection concurrently with the execution of the application. The application is paused for short periods during the collection. A parallel version of the young generation copying collector is used with the concurrent collector. The concurrent low pause collector is used if the option -XX:+UseConcMarkSweepGC is passed on the command line.

3. The incremental (sometimes called train) low pause collector: this collector is used only if -XX:+UseTrainGC is passed on the command line. This collector has not changed since the J2SE Platform version 1.4.2 and is currently not under active development. It will not be supported in future releases. Please see the 1.4.2 GC Tuning Document for information on this collector.

CMS GC Incremental mode

       當要使用 concurrent low pause collector時,在java的opt里加上 -XX:+UseConcMarkSweepGC。concurrent low pause collector還有一種爲CPU少的機器準備的模式,叫Incremental mode。這種模式使用一個CPU來在程序運行的過程中GC,只用很少的時間暫停程序,檢查對象存活。

       在Incremental mode裏,每個收集過程中,會暫停兩次,第二次略長。第一次用來,簡單從root查詢存活對象。第二次用來,詳細檢查存活對象。整個過程如下:

* stop all application threads; do the initial mark; resume all application threads(第一次暫停,初始話標記)
* do the concurrent mark (uses one procesor for the concurrent work)(運行是標記)
* do the concurrent pre-clean (uses one processor for the concurrent work)(準備清理)
* stop all application threads; do the remark; resume all application threads(第二次暫停,標記,檢查)
* do the concurrent sweep (uses one processor for the concurrent work)(運行過程中清理)
* do the concurrent reset (uses one processor for the concurrent work)(復原)

       當要使用Incremental mode時,需要使用以下幾個變量:

-XX:+CMSIncrementalMode default: disabled 啓動i-CMS模式(must with -XX:+UseConcMarkSweepGC)
-XX:+CMSIncrementalPacing default: disabled 提供自動校正功能
-XX:CMSIncrementalDutyCycle=<N> default: 50 啓動CMS的上線
-XX:CMSIncrementalDutyCycleMin=<N> default: 10 啓動CMS的下線
-XX:CMSIncrementalSafetyFactor=<N> default: 10 用來計算循環次數
-XX:CMSIncrementalOffset=<N> default: 0 最小循環次數(This is the percentage (0-100) by which the incremental mode duty cycle is shifted to the right within the period between minor collections.)
-XX:CMSExpAvgFactor=<N> default: 25 提供一個指導收集數

      SUN推薦的使用參數是:
-XX:+UseConcMarkSweepGC \
-XX:+CMSIncrementalMode \
-XX:+CMSIncrementalPacing \
-XX:CMSIncrementalDutyCycleMin=0 \
-XX:CMSIncrementalDutyCycle=10 \
-XX:+PrintGC Details \
-XX:+PrintGCTimeStamps \
-XX:-TraceClassUnloading
注:如果使用throughput collector和concurrent low pause collector,這兩種垃圾收集器,需要適當的挺高內存大小,以爲多線程做準備。

如何選擇collector:

  • app運行在單處理器機器上且沒有pause time的要求,讓vm選擇或者UseSerialGC.
  • 重點考慮peak application performance(高性能),沒有pause time太嚴格要求,讓vm選擇或者UseParallelGC+UseParallelOldGC(optionally).
  • 重點考慮response time,pause time要小,UseConcMarkSweepGC.

Garbage Collctor – Future

  • Garbage First(G1)
    jdk1.6 update 14 or jdk7
  • few flags need to set
    -XX:MaxGCPauseMillis=100
    -XX:GCPauseIntervalMillis=6000

     還沒嘗試過使用…

Summary

import java.util.ArrayList;
import java.util.List;
public class SummaryCase {
public static void main(String[] args) throws InterruptedException {
List<Object> caches = new ArrayList<Object>();
for (int i = 0; i < 7; i++) {
caches.add(new byte[1024 * 1024 * 3]);
Thread.sleep(1000);
}
caches.clear();
for (int i = 0; i < 2; i++) {
caches.add(new byte[1024 * 1024 * 3]);
Thread.sleep(1000);
}
}
}

用以下兩種參數執行,會執行幾次YGC幾次FGC?
  • -Xms30M -Xmx30M -Xmn10M  -Xloggc:gc.log -XX:+PrintTenuringDistribution -XX:+UseParallelGC
    2.062: [GC
    Desired survivor size 1310720 bytes, new threshold 7 (max 15)
    6467K->6312K(29440K), 0.0038214 secs]
    4.066: [GC
    Desired survivor size 1310720 bytes, new threshold 7 (max 15)
    12536K->12440K(29440K), 0.0036804 secs]
    6.070: [GC
    Desired survivor size 1310720 bytes, new threshold 7 (max 15)
    18637K->18584K(29440K), 0.0040175 secs]
    6.074: [Full GC 18584K->18570K(29440K), 0.0031329 secs]
    8.078: [Full GC 24749K->3210K(29440K), 0.0045590 secs]
    (具體分析見http://rdc.taobao.com/team/jm/archives/440)
  • -Xms30M -Xmx30M -Xmn10M  -Xloggc:gc.log -XX:+PrintTenuringDistribution -XX:+UseSerialGC
    2.047: [GC
    Desired survivor size 524288 bytes, new threshold 15 (max 15)
    - age 1: 142024 bytes, 142024 total
    6472K->6282K(29696K), 0.0048686 secs]
    4.053: [GC
    Desired survivor size 524288 bytes, new threshold 15 (max 15)
    - age 2: 141880 bytes, 141880 total
    12512K->12426K(29696K), 0.0047334 secs]
    6.058: [GC
    Desired survivor size 524288 bytes, new threshold 15 (max 15)
    - age 3: 141880 bytes, 141880 total
    18627K->18570K(29696K), 0.0049135 secs]
    8.063: [Full GC 24752K->3210K(29696K), 0.0077895 secs]
    (具體分析見http://rdc.taobao.com/team/jm/archives/458)

參考:

  1. http://jiangyongyuan.iteye.com/blog/356502
  2. http://www.helloying.com/blog/archives/164
  3. http://hi.baidu.com/sdausea/blog/item/c599ef13fcd3a7dbf6039e12.html
  4. Tuning Garbage Collection with the 1.4.2 JavaTM Virtual Machine .
  5. http://blog.bluedavy.com/?p=200
  6. http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章