1. 程式人生 > >Java虛擬機(三):GC算法和種類

Java虛擬機(三):GC算法和種類

完成 垃圾 過程 回收 對象復制 沒有響應 rip 加法 內存

一、介紹

  • GC(Garbage Collection),垃圾收集
  • Java中,GC的對象是堆空間和永久區

二、GC算法

1. 引用計數法

  • 老牌垃圾回收算法
  • 通過引用計算來回收垃圾
  • Java中未使用,使用者有COM、ActionScript3、Python

實現:

  1> 對於一個對象A,只要有任何一個對象引用了A,則A的引用計數器就加1;

  2> 當引用失效時,引用計數器就減1;

  3> 只要對象A的引用計數器的值為0,則對象A就不可能再被使用。

技術分享圖片

缺點:

  • 引用和去引用伴隨加法和減法,影響性能
  • 很難處理循環引用

技術分享圖片

2. 標記-清除算法

  • 標記-清除算法是現代垃圾回收算法的思想基礎。
  • 標記-清除算法將垃圾回收分為兩個階段:標記階段和清除階段。
  • 實現:
    • 在標記階段,首先通過根節點,標記所有從根節點開始的可達對象。因此,未被標記的對象就是未被引用的垃圾對象。
    • 在清除階段,清除所有未被標記的對象。

具體過程如下圖所示:

技術分享圖片

缺點:

  • 會產生大量不連續的內存碎片。可能會導致在需要分配較大對象時,無法找到足夠的連續的內存空間,而不得不提前進行另一次的垃圾收集動作。

3. 標記-壓縮算法

  • 標記-壓縮算法適合用於存活對象較多的場合,如老年代。
  • 它在標記-清除算法的基礎上做了一些優化。
    • 和標記-清除算法一樣,標記-壓縮算法也首先需要從根節點開始,對所有可達對象做一次標記。
    • 但之後,它並不簡單的清理未標記的對象,而是將所有的存活對象壓縮到內存的一端。
    • 最後,清理邊界外所有的空間。

具體過程如下圖所示:

技術分享圖片

4. 復制算法

  • 與標記-清除算法相比,復制算法是一種相對高效的回收方法
  • 不適用於存活對象較多的場合 如老年代
  • 將原有的內存空間分為兩塊,每次只使用其中一塊
    • 在垃圾回收時,將正在使用的內存中的存活對象復制到未使用的內存塊中,
    • 之後,清除正在使用的內存塊中的所有對象,
    • 最後,交換兩個內存的角色,完成垃圾回收

具體過程如下圖所示:

技術分享圖片

缺點:

  • 空間浪費,內存縮小為原來的一半。

5. 分代收集算法

  • 分代收集算法是目前大部分JVM的垃圾收集器采用的算法。
  • 依據對象的存活周期進行分類:短命對象歸為新生代,長命對象歸為老年代。
  • 根據不同代的特點,選取合適的收集算法
  • 少量對象存活(新生代),適合復制算法
  • 大量對象存活(老年代),適合標記清理或者標記壓縮

技術分享圖片

三、Stop-The-World

  • Java中一種全局暫停的現象
  • 全局停頓,所有Java代碼停止,native代碼可以執行,但不能和JVM交互
  • 多半由於GC引起
    •   Dump線程
    •   死鎖檢查
    •   堆Dump

GC時為什麽會有全局停頓?
  類比在聚會時打掃房間,聚會時很亂,又有新的垃圾產生,房間永遠打掃不幹凈,只有讓大家停止活動了,才能將房間打掃幹凈。

危害:

  • 長時間服務停止,沒有響應
  • 遇到HA系統,可能引起主備切換,嚴重危害生產環境。

Java虛擬機(三):GC算法和種類