java 虛擬機--新生代與老年代GC

1. Java堆中各代分佈: html

圖1:Java堆中各代分佈 java

Young:主要是用來存放新生的對象。 算法

Old:主要存放應用程序中生命週期長的內存對象。 數組

Permanent:是指內存的永久保存區域,主要存放Class和Meta的信息,Class在被 Load的時候被放入PermGen space區域. 它和和存放Instance的Heap區域不一樣,GC(Garbage Collection)不會在主程序運行期對PermGen space進行清理,因此若是你的APP會LOAD不少CLASS的話,就極可能出現PermGen space錯誤。 併發

 

2. JVM 使用的GC算法是什麼? spa

分代收集。 線程

即將內存分爲幾個區域,將不一樣生命週期的對象放在不一樣區域裏; 日誌

在GC收集的時候,頻繁收集生命週期短的區域(Young area); htm

比較少的收集生命週期比較長的區域(Old area); 對象

基本不收集的永久區(Perm area)。

 

3. GC 和 Full GC 有什麼區別?

GC(或Minor GC):收集 生命週期短的區域(Young area)。

Full GC (或Major GC):收集生命週期短的區域(Young area)和生命週期比較長的區域(Old area)對整個堆進行垃圾收集。

他們的收集算法不一樣,因此使用的時間也不一樣。 GC 效率也會比較高,咱們要儘可能減小 Full GC 的次數。 當顯示調用System.gc() 時,gc does a full collection(both young generation and tenured generation).

 

4. Minor GC後,Eden是空的嗎?

是的,Minor GC會把Eden中的全部活的對象都移到Survivor區域中,若是Survivor區中放不下,那麼剩下的活的對象就被移到Old generation 中。

 

5. Garbage collection options(JDK1.4):

圖2:GC參數

堆設置 
-Xms :初始堆大小 
-Xmx :最大堆大小 
-XX:NewSize=n :設置年輕代大小 
-XX:NewRatio=n: 設置年輕代和年老代的比值。如:爲3,表示年輕代與年老代比值爲1:3,年輕代佔整個年輕代年老代和的1/4 
-XX:SurvivorRatio=n :年輕代中Eden區與兩個Survivor區的比值。注意Survivor區有兩個。如:3,表示Eden:Survivor=3:2,一個Survivor區佔整個年輕代的1/5
-XX:MaxPermSize=n :設置持久代大小 
收集器設置 
-XX:+UseSerialGC :設置串行收集器 
-XX:+UseParallelGC :設置並行收集器 
-XX:+UseParalledlOldGC :設置並行年老代收集器 
-XX:+UseConcMarkSweepGC :設置併發收集器 
垃圾回收統計信息 
-XX:+PrintHeapAtGC GC的heap詳情
-XX:+PrintGCDetails  GC詳情
-XX:+PrintGCTimeStamps  打印GC時間信息
-XX:+PrintTenuringDistribution    打印年齡信息等
-XX:+HandlePromotionFailure   老年代分配擔保(true  or false)
並行收集器設置 
-XX:ParallelGCThreads=n :設置並行收集器收集時使用的CPU數。並行收集線程數。 
-XX:MaxGCPauseMillis=n :設置並行收集最大暫停時間 
-XX:GCTimeRatio=n :設置垃圾回收時間佔程序運行時間的百分比。公式爲1/(1+n) 
併發收集器設置 
-XX:+CMSIncrementalMode :設置爲增量模式。適用於單CPU狀況。 
-XX:ParallelGCThreads=n :設置併發收集器年輕代收集方式爲並行收集時,使用的CPU數。並行收集線程數。

 

6. 例子:Heap size 設置

場景:在JAVA_HOME下demo/jfc/SwingSet2/目錄下執行下面的命令:

    java -jar -Xmn4m -Xms16m -Xmx16m SwingSet2.jar

系統輸出:

 

Exception in thread "Image Fetcher 0" java.lang.OutOfMemoryError: Java heap space

Exception in thread "Image Fetcher 3" java.lang.OutOfMemoryError: Java heap space

Exception in thread "Image Fetcher 1" java.lang.OutOfMemoryError: Java heap space

Exception in thread 「Image Fetcher 2」 java.lang.OutOfMemoryError: Java heap space

調優:將-Xms和-Xmx選項設置爲32m,而-Xmn爲1/4的-Xmx值。

結果:執行java -jar –Xmn8m –Xms32m -Xmx32m SwingSet2.jar,系統正常運行。

 

7. JVM  Runtime Data Area(運行時數據區):

圖3:JVM運行時數據區(一)

Heap: JVM只有一個爲全部線程所共享的堆,全部的類實例和數組都是在堆中建立的。

Method area: JVM只有一個爲全部的線程所共享的方法區。它存儲類結構,例如運行時常量池,成員和方法數據以及方法、構造方法的代碼。

Java Stacks:每一個JVM線程擁有一個私有的棧。

Pc registers: JVM能夠同時支持運行多個線程,所以每一個線程須要各自的PC(program counter)寄存器。

Native method stacks: 保存native方法進入區域的地址 。

 

圖4:JVM運行時數據區(二)

Heap和Method area被全部線程共享,其生存期和JVM的生存期相同;Java Stacks、Pc registers、Native method stacks被每一個線程獨自擁有,其生存期和線程的生存期相同。

 

 

 

8. 常見的內存泄露錯誤

不少開發人員都碰到過java.lang.OutOfMemoryError的錯誤。這種錯誤又分兩種:java.lang.OutOfMemoryError: Java heap space和java.lang.OutOfMemoryError: PermGen space。引發這種錯誤的緣由多是程序問題,也多是是JVM參數配置問題引發的。如果參數問題,前者能夠同過配置-Xms和-Xmx參數來設置,然後者能夠經過配置 -XX:PermSize和-XX:MaxPermSize來設置。

                            

9. 參考資料:

 

1.  A brief history of garbage collection –

http://www-128.ibm.com/developerworks/java/library/j-jtp10283/

2.  Garbage collection in the HotSpot JVM –

http://www-128.ibm.com/developerworks/java/library/j-jtp11253/

3.  Tuning Garbage Collection with the 5.0 JavaTM Virtual Machine

http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html

4.  Diagnosing a GC problem –

http://java.sun.com/docs/hotspot/gc1.4.2/example.html

五、http://www.precisejava.com

 

GC (minor )日誌
Full GC 日誌
-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8 -XX:-HandlePromotionFailure -XX:+PrintHeapAtGC -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -XX:+PrintTenuringDistribution
相關文章
相關標籤/搜索