深入理解Java虛擬機器之讀書筆記二 垃圾收集器

來源:互聯網
上載者:User

標籤:弱引用   自適應   lib   方法區   暫停   組合   loader   預設   load   

1、對象已死?

a、引用計數演算法:缺點是它很難解決對象之間的相互循環參考的問題,Java語言中沒有選用它。

b、根搜尋演算法(GC Roots Tracing):通過一系列的名為“GC Roots”的對象作為起始點,開始向下搜尋,走過的路徑稱為引用鏈,當一個對象沒有任何引用鏈相連,表面此對象不可達。在Java語言中,可作為GC Roots的對象包括:

  虛擬機器棧(棧幀中的本地變數表)中的引用的對象。

  方法區中的類靜態屬性引用的對象。

  方法區中的常量引用的對象。

  本地方法棧中JNI的引用的對象。

c、再談引用:Java把引用分成強引用,軟引用,弱引用和虛引用。由強到弱。

  強引用:只要強應用在存在,垃圾收集器永遠不會回收掉被引用的對象。

  軟引用:在系統將要發生記憶體溢出異常之前,把對象列進回收範圍之中並進行第二次回收。如果這次回收之後還是沒有足夠的記憶體,才會拋出記憶體溢出異常。SoftReference

  弱引用:被弱引用關聯的對象只能生存到下一次記憶體回收發生之前。WeakReference

  虛引用:一個對象是否有虛引用的存在,完全不會對其存留時間構成影響,也無法通過虛引用來取得一個對象執行個體。唯一目的是:對象被回收時收到一個系統通知。PhantomReference

d、生存還是死亡?

  對象不可達之後,進入“緩刑”階段。第一次根搜尋後,不可達對象有兩種情況:一是直接回收,二是放入F-Queue隊列。放入F-Queue隊列的條件是覆蓋了finalize()方法且沒有被調用過。總結一下就是:對象可以通過覆蓋finalize()方法在被GC時拯救自己一次。注意:任何一個對象的finalize()方法都只會被系統自動調用一次。

e、回收方法區

  方法區的回收主要集中在:廢棄常量和無用的類。廢棄常量的回收與Java堆對象的回收類似,無用類的回收需要滿足3個條件:而且只是可以回收,通過參數控制。

  該類的所有執行個體都已經被回收

  載入該類的ClassLoader已經被回收

  該類對應的Class對象沒有在任何地方被引用。

  在大量使用反射、動態代理、CGLib等bytecode架構的情境,以及動態產生JSP和OSGi這類頻繁自訂ClassLoader的情境都需要虛擬機器具備類卸載的功能。

2、垃圾收集演算法

  a、標記-清除演算法:分成標記和清除兩個階段。首先標記出所有需要回收的對象,標記完成後統一回收掉所有被標記的對象。

  有點:實現簡單,邏輯直接

  缺點兩個:效率比較低,空間不連續,大量片段。

  b、複製演算法:為瞭解決效率問題。平分記憶體成兩塊,每次只用一塊,快用完時,複製替換。

  優點:實現簡單,運行高效

  缺點兩個:可用記憶體是原來的一半;當對象存活率較高時,複製帶來低效率。

  HotSpot虛擬機器吻合了IBM的研究,改進了該演算法,分成了一個較大的Eden區和兩個較小的Survivor區。效率更好,但需要擔保記憶體。比較符合新生代使用。

  c、標記-整理演算法:不直接清理可回收對象,讓所有存活的對象向一端移動,然後清理掉邊界以外的記憶體。比較適合於老年代使用。

  d、分代收集演算法:根據對象的存活周期不同將記憶體劃分為幾塊。根據各個年代的特點採用最合適的收集演算法。新生代一般使用複製演算法,老年代採用標記-清除演算法或者標記-整理演算法。

3、垃圾收集器

  

  展示了7種作用於不同分代的收集器,連線表示收集器之間可以搭配使用。

  a、Serial收集器:

  它是一個單線程的收集器,只會使用一個CPU和一條收集線程去完成垃圾收集工作。同時,它也是串列收集器:在進行垃圾收集時,必須暫停其他所有的背景工作執行緒(Stop The World),直到它收集結束。在使用者不可見的情況下,把使用者的正常背景工作執行緒全部停掉。

  這個簡單而高效(特別是單個CPU的環境)的收集器適合於運行在Client模式下的虛擬機器。

  b、ParNew收集器

  是Serial收集器的多線程版本,與Serial收集器唯一的區別就在於使用了多條線程進行收集。

  目前只有Serial和ParNew能與CMS收集器配合工作。CMS是JDK1.5中引入的第一款並發收集器:垃圾收集線程與使用者線程可同時工作。ParNew在多CPU的情況下才具備效能優勢。

  c、Parallel Scavenge收集器

  是一個新生代收集器,使用複製演算法,並行多線程收集器。它的特點是關注於達到一個可控制的輸送量,最大地利用CUP的時間。同時,Parallel Scavenge收集器通過一個切換參數還可以開啟自適應調節策略。

  d、Serial Old收集器

  它是Serial收集器的老年代版本,單線程,標記-整理演算法。主要用於Client模式下。同時:可以Parallel Scavenge收集器搭配使用,作為CMS收集器的後背預案。

  e、Parallel Old收集器

  它是Parallel Scavenge收集器的老年代版本,多線程和標記-整理演算法。與Paralle Scavenge一起打造輸送量優先的組合。在注重輸送量及CPU資源敏感的場合,考慮使用。

  f、CMS收集器(Concurrent Mark Sweep)

  以擷取最短回收停頓時間為目標,適合於注重服務的相應速度的場合。基於標記-清除演算法。整個過程四個步驟:

  初始標記(CMS initial mark)

  並發標記(CMS concurrent mark)

  重新標記(CMS remark)

  並發清除(CMS concurrent sweep)

  注意:初始標記和重新標記一樣有Stop The World。初始標記只是標記一下GC Roots能直接關聯到的對象,速度很快,並發標記階段就是進行Roots Tracing的過程,而重新標記則是為了修正並發標記期間,因使用者程式運作而導致標記發生變動的那一部分對象的標記記錄,停頓時間不長。耗時較長的並發標記和並發清除過程,收集線程和使用者線程可一起工作。

  缺點:

  對CPU資源非常敏感。預設啟動線程數:(CPU數量+3)/4。

  無法處理浮動垃圾,可能出現Concurrent Mode Failure失敗導致一次Full GC。CMS運行期間預留的記憶體無法滿足程式的需要,出現Concurrent Mode Failure失敗。虛擬機器啟動後備預案,臨時使用Serial Old收集器重新老年代的垃圾收集。

  使用的標記-清除演算法導致大量記憶體片段。可能導致提前Full GC。使用參數可控制Full GC發生後附帶的空間磁碟重組頻率。

  g、G1收集器

  與CMS相比有兩個改進:基於標記-整理演算法,消除了記憶體片段問題;精確地控制停頓時間長度。G1將整個Java堆分成多個大小固定的獨立地區,跟蹤地區垃圾堆積程度,在後台維護一個優先列表,每次根據允許的收集時間,優先收集垃圾最多的地區。

  4、垃圾收集器參數總結

 

深入理解Java虛擬機器之讀書筆記二 垃圾收集器

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.