JVM之GC演算法

來源:互聯網
上載者:User

標籤:參考   1.0   垃圾   tin   執行   進入   整理   相等   記憶體地區   

1. 前言

  1.1 概念:清理記憶體中不會再被使用的對象

  1.2 背景:如果記憶體中的垃圾不被清理,會導致記憶體溢出

  1.3 常用的記憶體回收演算法:引用計數法(Reference Counting)、標記清除法(Mark-Sweep)、複製演算法(Copying)、標記壓縮法(Mark-Compact)、分代演算法(Generational Collecting)及分區演算法(Region)

 

2. 演算法演化

  2.1 引用計數法【Java記憶體回收未採用】

    2.1.1 思想:對於對象A,如果被引用,A的引用計數器就+1;當引用失效時,A的引用計數器-1.當對象A的引用計數器的值為0,則對象A被回收。

    2.1.2 缺陷:

      2.1.2.1  無法處理循環參考的情況。【例如:對象A和對象B相互引用,卻沒有被其他對象引用。此時,A和B應該被回收。然而,對象A和B的引用計數器卻不為0,無法被回收。】 

      2.1.2.2 每次對象被引用/釋放引用的時候,都會伴隨著運算操作,對系統效能會有一定的影響。

 

因為循環參考的對象無法被回收,為瞭解決該缺陷,於是產生了可達對象的概念。根據可達對象的概念,產生了標記清除法。

 

  2.2 標記清除法【現代記憶體回收演算法的基礎】

    2.2.1 基礎:

      2.2.1.1 可達對象:通過根對象進行引用搜尋,最終可以達到的對象。

      2.2.1.2 不可達對象:通過根對象進行引用搜尋,最終沒有被引用到的對象。

     2.2.2 思想:通過標記、清除兩個階段實現記憶體回收

      2.2.2.1 標記階段:根據根節點,標記所有的可達對象

      2.2.2.2 清除階段:清除所有的不可達對象

    2.2.3 缺陷:

      2.2.3.1 產生大量的空間片段,工作效率低

      標記清除法是對一塊連續的空間進行回收,回收後的空間是不連續的【】。在對象的堆空間分配過程中,尤其是大對象的記憶體配置,不連續記憶體空間的工作做效率要低於連續空間。

 

 

因為不連續記憶體空間的工作效率低,為瞭解決這個問題,於是想到:新開闢一個工作空間,將可達對象複製到新的記憶體空間,保證空間使用的連續性。

  

  2.3 複製演算法【新生代演算法】

    2.3.1 思想:將原有的記憶體空間分為兩塊,每次使用其中一塊。記憶體回收時,將正在使用的記憶體中的可達對象複製到未使用的記憶體塊中,清除正在使用的記憶體塊中的所有對象,交換兩個記憶體的角色,完成回收。

 

  2.3.2 缺陷:

    2.3.2.1 將系統記憶體折半,佔用的系統記憶體太大。

 

複製演算法的高效性是建立在存活對象少,垃圾對象對象多的前提下。對於存活對象多的情況,複製成本高,需要其它演算法來替代。

 

  2.4 標記壓縮法【老年代演算法】

    2.4.1 原理:標記清除演算法執行完成後,再進行一次記憶體磁碟重組。

    2.4.2 思想:從根節點出發,將所有的可達對象進行標記,然後將標記對象壓縮到記憶體的一端。最後,清除邊界之外的所有空間。

 

 

在上述演算法中,它們都有各自獨特的優勢,並沒有一種演算法可以完全替代其它演算法。因此,正確的方式是:根據記憶體回收對象的特性,使用合適的演算法回收。基於這種情況,產生了分代的思想。

  2.5 分代演算法

    2.5.1 思想:根據對象的特點,將記憶體地區分成幾塊;根據每塊記憶體地區的特點,使用不同的回收演算法。               

    2.5.2 應用:新生代使用複製演算法,老年代使用標記壓縮法。

 

既然可以根據對象的生命週期(時間角度)進行回收,那麼根據對象的空間分布(空間角度)也可以進行回收。

  

  2.6 分區演算法

    2.6.1 背景:在相同條件下,堆空間越大,一次GC所用的時間越長,從而產生的停頓也越長。

    2.6.2 思想:將堆空間劃分成連續的小地區,每個小地區獨立使用、獨立回收。

 

3. 補充

  3.1 新生代串列記憶體回收行程中,使用複製演算法的思想。

    3.1.1 基礎:新生代分為eden區、from區、to區。其中,from區和to區也被稱為survivor區,可以視為用於複製的大小相等、地位相等、且可以角色互換的兩個空間塊。

    3.1.2 思路:記憶體回收時,Eden區和正在使用的survivor區(假設是from區)中的可達對象會被複製到未被使用的survivor區(to區),然後清空Eden區和from區。

    3.1.3 備忘:from區中的大對象或者老年對象會直接進入老年區;如果to區空間不足,對象也會進入老年區

  3.2 複製演算法的高效性是建立在可達對象少,不可達對象多的前提下,因此複製演算法只用於新生代【新生代,垃圾對象通常會多於存活對象;老年代大部分對象都是存活對象】。老年代採用標記壓縮法

  3.3 新生代GC與老年代GC對比:

 

 

4. 附錄

  4.1 參考文獻:《實戰Java虛擬機器 – JVM故障診斷與效能最佳化》 葛一鳴著

JVM之GC演算法

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.