JVM學習總結二——垃圾回收算法

    昨天總結了JVM內存分區相關的知識,此次咱們未來了解下JVM的另外一個核心知識點——垃圾回收算法。這一部分其實並不太難,若是對操做系統的內存處理算法有所瞭解,那麼這部分算法其實只看名字就能明白,二者在原理上是同樣的,並且JVM的相對更爲簡單點。

    在初學JVM的時候,咱們每每會對這部分感到迷惑:網上很多博客介紹的五花八門,像引用計數算法、串行、並行、併發算法等,他們到底算不算垃圾回收算法,算的話又和基本的那幾個算法有什麼關係呢?(PS:其實若是認真看過書的話,就不會疑惑了,由於書裏邊介紹的很清晰),下邊咱們來理一下這些算法的關係: java

  • 對象存活判斷算法:引用計數、可達性分析
  • 基本的垃圾回收算法:標記-清除、複製、標記-整理
  • 依賴線程實現的回收算法:串行、並行、併發
    其中對象存活斷定算法是其餘算法的基石,用來判斷對象是否存活,可否回收;基本的垃圾回收算法是垃圾垃圾收集器實現的基礎算法;而依賴線程實現的算法,則是基本算法在考慮線程環境下的運用,這個有多線程基礎的看名字就明白了。此外,還有綜合以上算法並從特定角度實現的算法,如分代回收(針對分區)、增量回收(針對實時性)等,在此再也不介紹

1、對象存活判斷算法

   在咱們回收一個對象以前,咱們首先要搞明白的一點是這個對象是否是已經死了(沒有用了),而對於java程序而言,當一個對象再也不被引用,那麼他就死了(沒被引用就沒法被正常訪問了)。爲實現這個判斷,可使用兩種算法實現:引用計數可達性分析
    引用計數實現計較簡單,每一個對象對應一個引用計數器,當有被引用的時候就+1,引用被釋放的時候-1,這樣當該值爲0時,則對象已死。這一算法有個問題就是:當出現相互引用(相似於多線程死鎖的狀況)的時候,對象雖死,可是計數器卻不爲0。
    可達性分析也叫根節點搜索算法,其實現是根據圖的搜索(固然,圖的搜索其實就是樹遍歷),JVM首先建立一個GC Root的根節點,全部建立的對象在存活的時候都能根據引用關係找到到達該根節點的路徑,若是找不到路徑,則說明該對象已死。這一算法不只解決了引用計數的缺陷,並且不用每一對象都維護一個計數器,目前最經常使用的HotSpot虛擬機就採用該算法。 算法

2、基本垃圾回收算法

    所謂算法,就是在時間、空間、實現複雜度這三者的互博中尋求一個最優的實現。而幾種垃圾回收算法也是在這幾個方面各有側重。
    標記-清除算法分爲兩個階段:先對回收對象進行標記,而後統一回收。這種思路很簡單,實現也很容易,可是卻頭兩個缺點:一是標記、清除效率都很低,二是會產生碎片化,清除後空出來的空間是零散的。
    複製算法是將內存空間分爲兩個部分,對象同時只存在其中一個裏邊,當回收時將存活對象複製到另外一區便可,這樣就不用再進行清除了(直接覆蓋便可),還不會產生生碎片。以前提到分代回收中Eden去的survivor便使用該算法。可是該算法缺點也很明顯,有一半空間浪費了,典型的空間換時間。
    標記-整理算法標記-清除的升級版,上邊說到,清理過程也是效率很低的,那麼該算法第二步就不進行清理,而是將對象向前移動,覆蓋該回收的區域,這樣整理後就不會產生碎片了。年老代通常採用該算法。
    該部分可參考 服務器

3、串行、並行、併發垃圾回收器

    首先咱們要提到一點是,垃圾回收因爲涉及對內存的整理,要求整理時內存狀態是不能被程序改變的,也就是Stop-The-World模式下進行。當gc時間過長時,程序會出現長時間停頓,這對於響應較高的應用是不可接受的。所以,在結合線程後實現了不一樣方式的收集器,以知足不一樣需求。
多線程

  • 串行收集:串行收集使用單線程處理全部垃圾回收工做,由於無需多線程交互,實現容易,並且效率比較高。可是,其侷限性也比較明顯,即沒法使用多處理器的優點,因此此收集適合單處理器機器。固然,此收集器也能夠用在小數據量(100M左右)狀況下的多處理器機器上。通常只能用於小型應用
  • 並行收集:並行收集使用多線程處理垃圾回收工做,於是速度快,效率高。並且理論上CPU數目越多,越能體現出並行收集器的優點。 適用狀況:「對吞吐量有高要求」,多CPU、對應用響應時間無要求的中、大型應用。舉例:後臺處理、科學計算。
  • 併發收集:相對於串行收集和並行收集而言,前面兩個在進行垃圾回收工做時,須要暫停整個運行環境,而只有垃圾回收程序在運行,所以,系統在垃圾回收時會有明顯的暫停,並且暫停時間會由於堆越大而越長。適用狀況:「對響應時間有高要求」,多CPU、對應用響應時間有較高要求的中、大型應用。舉例:Web服務器/應用服務器、電信交換、集成開發環境。
    此外還要提到的一點是,由於不一樣系統、不一樣JVM對於線程的處理不一樣,因此這幾個算法的的實現都是依賴於垃圾收集器的實現的,咱們能夠經過JVM參數來指定不一樣收集器進行處理。

    本次JVM相關算法介紹完畢,下次將重點放在JVM監控、調優等方面,因爲我的沒有太多實踐經驗,這部分主要會整理相關資料。     併發

相關文章
相關標籤/搜索