天天看點

深入了解java虛拟機-2 垃圾收集器

1.對象已死?

1.引用計數算法

2.可達性分析算法

2.引用

1.強引用

2.軟引用

3.弱引用

4.虛引用

作用:在這個對象被回收時,收到一個系統通知

3.Finalize

一個對象死亡的過程

發現沒有和GC Roots相連接配接->被标記一個,并檢測,是否有必要執行Finalize方法->Yes的話被放入F-Queue中

->稍後GC對 F-Queue隊列進行标記->對象如果在finalize中拯救了自己,他将被移出即将回收隊列

這個方法不同于C++析構函數,不建議使用

4.垃圾收集算法

1.标記-清除算法

兩個不足:效率問題,标記與清除兩個功能效率都不高;空間問題,會産生大量碎片

2.複制算法

簡單,高效,代價是犧牲一半的記憶體

适合新生代

3.标記-整理算法

先進行标記,然後讓存活下來的向一邊移動,然後清理掉邊界外的記憶體

4.分代收集算法

根據對象存活周期不同,将記憶體劃分為幾塊,新生代使用2複制算法。老年代使用标記清除或标記整理算法

5.HotSpot算法實作-虛拟機如何發起記憶體回收

1.枚舉根節點

枚舉根節點時必須保證分析過程中對象的引用關系沒有變化。枚舉根節點時,虛拟機一定會停頓。

主流虛拟機使用精确式GC,HotSpot中使用OopMap的資料結構來定位對象引用。

2.安全點

Hotspot會在特定位置記錄了對象引用到OopMap,這個位置就是安全點。

安全點標明問題:

如何讓所有線程都跑到“安全點停下來那?

1.搶占式中斷

先把所有線程都中斷,然後讓沒有在安全點的,恢複線程,讓他跑到安全點(這種方法幾乎沒有人使用了)

2.主動式中斷”

不直接操作線程,僅設定一個标志,這個标志與安全點重合,執行到安全點就完成線程中斷

3.安全區域

安全區域:是引用關系不會發生變化的一段代碼片段,這個區域裡面任何地方GC都是安全的。

6.HotSpot算法實作-垃圾收集器

前面三個都是新生代收集器,使用的都是複制算法

1.Serial收集器

單線程收集器,運作在Client模式下面的預設新生代收集器。 特點:簡單且高效;對于單個CPU的情況下,沒有線程直接的互動,效率更高。

2.PerNew收集器

PeriNew 是Serial的多線程版本,一個并行的多線程收集器。是很多在Server下面首選的新生代收集器,與性能無關的原因是:目前隻有他能與CMS收集器配合工作。

3.Parallel Scavenge收集器

特點:

1,吞吐量優先收集器 2,于PeiNew差別是,這個收集器采用自适應調節政策 這個收集器的目的是達到一個可控制的吞吐量。吞吐量=運作使用者代碼時間/(運作使用者代碼時間+垃圾收集時間) 參數詳解: 1,-XX:MaxGCPauseMillis

設定記憶體回收不超過的時間,GC停頓時間縮短是以犧牲性能和新生代空間來保證的。

2,-XX:GCTimeRadtio

設定垃圾收集時間所占比重。(0<n<100)

3.-XX:UserAdaptiveSizePolicy

隻需設定好基本的記憶體資料,然後剩下的交給虛拟機自動完成

4,Serial Old收集器

标記整理算法 單線程收集器,和Serial一樣用于Client模式下老年代收集。 兩大用途: 在jdk1.5以及之前與Parallel Old收集器搭配使用 CMS收集器後備方案

5,Parallel Old收集器

标記整理算法

Parallel Scavenge老年化版本,

在注重吞吐量和CPU資源敏感的地方使用 Parallel Scavenge 和Parallel Old 組合

6,CMS收集器

并發低停頓收集器 标記-清除算法 CMS收集器的目的是擷取最短回收停頓時間。CMS适合 網際網路站和B/S系統伺服器端,這種要求響應時間的 步驟: 1.初始标記 需要stop the world,标記GC Root能關聯到的對象 2,并發标記 從GC Roots 對對象進行可到達性分析,找出存活的對象 3,重新标記 需要stop the world,修正并發期間變動的那部分對象的标記記錄 4,并發清除 花費時間最長的并發标記與并發清除是可以并行的, CMS的缺點: 1.對CPU資源比較敏感,CPU不足4個時,CMS對客戶程式影響較大 2.無法處理浮動垃圾,就是在并發清除過程中産生的垃圾,CMS無法再當次進行中收集他們 而且,由于CMS是并發的收集器是以不能等到老年代幾乎快滿了再收集,預設68%, -XX:CMSInitiatingOccupancyFraction 用來提高觸發百分比 如果運作期間,預留的記憶體空間無法滿足CMS收集垃圾,就會啟動備用方案,Serial Old收集器.是以-XX:CMSInitiatingOccupancyFraction設定太高反而性能降低 3.基于标記-清除,會有大量碎片産生 -XX:UseCMSCompactAtFullCollection 開關參數,模式是開啟,用于開啟記憶體碎片這個能力過程 -XX:CMSFUllGCsBeforeCompaction 多少次不執行壓縮的FullGC後,來一次帶壓縮的

7,G1收集器

面向伺服器端應用的垃圾收集器 特點: 1.并行與并發 2.分代收集 3.空間整合,使用标記整理算法,不會産生記憶體碎片 4.可預測的停頓,不僅追求地停頓,還建立了可預測時間的模型

步驟: 1.初始标記 需要stop the world,标記GC Root能關聯到的對象 2,并發标記 從GC Roots 對對象進行可到達性分析,找出存活的對象 3,最終标記 修正并發期間變動的那部分對象的标記記錄 4,篩選回收 

JVM 參數

XX:+<option> 啟用選項 -XX:-<option> 不啟用選項 -XX:<option>=<number>  -XX:<option>=<string>

附錄:參數 描述

-XX:+UseSerialGC Jvm運作在Client模式下的預設值,打開此開關後,使用Serial + Serial Old的收集器組合進行記憶體回收
-XX:+UseParNewGC 打開此開關後,使用ParNew + Serial Old的收集器進行垃圾回收
-XX:+UseConcMarkSweepGC 使用ParNew + CMS +  Serial Old的收集器組合進行記憶體回收,Serial Old作為CMS出現“Concurrent Mode Failure”失敗後的後備收集器使用。
-XX:+UseParallelGC Jvm運作在Server模式下的預設值,打開此開關後,使用Parallel Scavenge +  Serial Old的收集器組合進行回收
-XX:+UseParallelOldGC 使用Parallel Scavenge +  Parallel Old的收集器組合進行回收
-XX:SurvivorRatio 新生代中Eden區域與Survivor區域的容量比值,預設為8,代表Eden:Subrvivor = 8:1
-XX:PretenureSizeThreshold 直接晉升到老年代對象的大小,設定這個參數後,大于這個參數的對象将直接在老年代配置設定
-XX:MaxTenuringThreshold 晉升到老年代的對象年齡,每次Minor GC之後,年齡就加1,當超過這個參數的值時進入老年代
-XX:UseAdaptiveSizePolicy 動态調整java堆中各個區域的大小以及進入老年代的年齡
-XX:+HandlePromotionFailure 是否允許新生代收集擔保,進行一次minor gc後, 另一塊Survivor空間不足時,将直接會在老年代中保留
-XX:ParallelGCThreads 設定并行GC進行記憶體回收的線程數
-XX:GCTimeRatio GC時間占總時間的比列,預設值為99,即允許1%的GC時間,僅在使用Parallel Scavenge 收集器時有效
-XX:MaxGCPauseMillis 設定GC的最大停頓時間,在Parallel Scavenge 收集器下有效
-XX:CMSInitiatingOccupancyFraction 設定CMS收集器在老年代空間被使用多少後出發垃圾收集,預設值為68%,僅在CMS收集器時有效,-XX:CMSInitiatingOccupancyFraction=70
-XX:+UseCMSCompactAtFullCollection 由于CMS收集器會産生碎片,此參數設定在垃圾收集器後是否需要一次記憶體碎片整理過程,僅在CMS收集器時有效
-XX:+CMSFullGCBeforeCompaction 設定CMS收集器在進行若幹次垃圾收集後再進行一次記憶體碎片整理過程,通常與UseCMSCompactAtFullCollection參數一起使用
-XX:+UseFastAccessorMethods 原始類型優化
-XX:+DisableExplicitGC 是否關閉手動System.gc
-XX:+CMSParallelRemarkEnabled 降低标記停頓
-XX:LargePageSizeInBytes 記憶體頁的大小不可設定過大,會影響Perm的大小,-XX:LargePageSizeInBytes=128m

Client、Server模式預設GC

  新生代GC方式老年代和持久 代GC方式

Client Serial 串行GC Serial Old 串行GC
Server Parallel Scavenge  并行回收GC Parallel Old 并行GC

Sun/oracle JDK GC組合方式

  新生代GC方式老年代和持久 代GC方式

-XX:+UseSerialGC Serial 串行GC Serial Old 串行GC
-XX:+UseParallelGC Parallel Scavenge  并行回收GC Parallel Old 并行GC
-XX:+UseConcMarkSweepGC ParNew 并行GC

CMS 并發GC 

當出現“Concurrent Mode Failure”時

采用Serial Old 串行GC

-XX:+UseParNewGC ParNew 并行GC Serial Old 串行GC
-XX:+UseParallelOldGC Parallel Scavenge  并行回收GC Parallel Old 并行GC

-XX:+UseConcMarkSweepGC

-XX:+UseParNewGC

Serial 串行GC

CMS 并發GC 

當出現“Concurrent Mode Failure”時

采用Serial Old 串行GC

參數部分參考自:http://blog.csdn.net/huxian1234/article/details/17163023

繼續閱讀