1. 程式人生 > >讀書筆記-深入理解Java虛擬機器#2

讀書筆記-深入理解Java虛擬機器#2

一、物件已死

  • 引用計數演算法,引用加1,失效減1;為0時被回收。
  • 可達分析演算法,從GC Root開始搜尋,當一個物件在GC ROOT沒有任何引用鏈則物件不可用。
  • GC ROOT 物件包括下面幾種: 1.虛擬機器棧中引用的物件; 2.方法區中類靜態屬性引用的物件; 3.方法區中常量引用的物件; 4.本地方法棧中引用的物件;

引用分為強引用,軟引用,弱引用,虛引用 - 強引用指程式碼普遍存在,類似 Object obj = new Object(),只要強引用在永遠不會被回收; - 軟引用是描述一些有用但非必須的物件,系統記憶體溢位異常前,會把這些物件回收; - 弱引用是描述非必須物件,強度比軟引用更弱一些,每次垃圾收集器工作時,無論記憶體是否夠都會被回收; - 虛引用稱幽靈引用,是最弱的引用關係,設定虛引用的唯一目的是物件被回收時收到一個系統通知;

判斷一個類是否是無用的類,需同時滿足:

  • 該類所有例項都已經被回收;
  • 載入該類的ClassLoader已被回收;
  • 該類對應的java.lang.Class物件沒有在其他地方被引用 ;

二、垃圾收集演算法

標記-清除演算法

  • 分為標記和清除兩個階段:首先標記處需回收物件,完成後統一回收。
  • 不足:1.效率問題 2.空間問題,清除後產生大量不連續記憶體碎片 這裡寫圖片描述

複製演算法

  • 將記憶體按容量劃分為大小相等的兩塊,每次使用其中一塊,當一塊用完了,將存活物件複製到另一塊,並清理舊塊
  • 實現簡單,執行高效,但記憶體使用縮小一半 這裡寫圖片描述

標記-整理演算法

這裡寫圖片描述

分代收集演算法

  • java堆分為新生代和老年代
  • 新生代選用複製演算法,老年代採用標記-清理或者標記-整理演算法

三、HotSpot的演算法實現

列舉根節點

  • 可達性分析必須在一個能確保一致性的快照中進行–Stop-The-World。
  • 虛擬機器通過OopMap的資料結構得知哪些地方存放著物件引用。

安全點

  • 在特定的位置生成OopMap,這些位置稱為安全點。
  • 程式執行只有在安全點時才會暫停。
  • 安全點不能太少以致於GC等待時間太長,也不能過於頻繁以致於過分增大執行負荷。
  • 安全點選定以是否具有讓程式長時間執行的特徵為標準,如方法呼叫,迴圈跳轉,異常跳轉。
  • 如何讓所有執行緒都在安全點處停頓:搶先式中斷和主動式中斷 1.搶先式中斷不需要程式碼配合,GC時把所有執行緒中斷,發現不在安全點處執行緒讓其跑到安全點上中斷。 2.主動式是當需要中斷時,不直接操作執行緒而設定一個標誌,各執行緒主動去輪詢這個標誌,發現標誌為真則中斷掛起。

安全區域

  • 安全區域指在一段程式碼片段之中,引用關係不會發生變化,在這區域中任意地方GC都是安全的。

四、垃圾收集器

Serial收集器

  • 一個單執行緒的收集器。
  • 對於執行在Client模式下的虛擬機器是個很好選擇。

    ParNew收集器

  • Serial收集器的多執行緒版本。

  • 並行(Parallel)指多條垃圾收集器執行緒並行工作,此時使用者執行緒處於等待狀態。
  • 併發(Concurrent)指使用者和收集器執行緒同時執行(可能交替執行),使用者程式繼續執行,收集器執行另一個CPU上。

Parallel Scavenge收集器

  • 新生代的收集器,也是使用複製演算法的收集器,又是並行的多執行緒收集器。
  • -XX:MaxGCPauseMillis 控制最大垃圾收集器停頓時間,GC停頓時間縮短以犧牲吞吐量和新生代空間來換取的。
  • -XX:GCTimeRatio 設定吞吐量大小(0-100)。
  • -XX:+UseAdaptiveSizePolicy 開啟後不需要指定新生代大小(-Xmn)、Eden與Surviror區比例等引數。

Serial Old收集器

  • Serial收集器的老年代版本。
  • 意義在於給Client模式的虛擬機器使用。

    Parallel Old收集器

  • Parallel Scavenge的老年代版本。

    CMS收集器

  • 以獲取最短回收停頓時間為目標的收集器,基於標記-清除演算法實現。

    G1收集器

  • 面向服務端應用的垃圾收集器。

  • 將整個java堆分為多個大小相等的獨立區域,新生代和老年代都是一部分割槽域的集合。

五、記憶體分配與回收策略

物件優先在Eden分配

  • 物件在新生代Eden分配,沒有空間會發起一次Minor GC。
  • 新生代GC(Minor GC)指發生在新生代垃圾收集動作,非常頻繁,回收速度也比較快。
  • 老年代GC(Full GC)指發生在老年代GC,比Minor GC速度慢10倍以上。

    大物件直接進入老年代

  • 大量連續佔用記憶體的物件,典型的是長字串以及陣列。

  • -XX:PretenureSizeThreshold 令大於這個設定值的物件直接在老年代分配,避免在Eden與survivor直接記憶體複製。
  • 上面引數只對Serial和ParNew兩款收集器有效。

長期存活的物件將進入老年代

動態物件年齡判定

空間分配擔保