1. 程式人生 > >JVM GC簡介

JVM GC簡介

GC垃圾回收

    本章節主要針對於以下三個問題的兩個問題進行描述。

如何判定為垃圾物件?

  • 引用計數法

        在物件中新增一個引用計數器,當有地方引用這個物件的時候這個引用計數器的值就+1,當引用計數器失效的時候,計數器的值就-1。當引用計數器為0就判斷為垃圾物件。     圖解(靈魂畫手又重出江湖啦哈哈哈哈哈哈哈哈):     假設棧中有一個指向(直接引用或者控制代碼的方式)堆中的物件,如果我們把引用置為null,那麼引用計數器就會-1.當垃圾回收器發現引用計數器為0就會進行回收。     缺點:如果物件之間屬性相互引用,棧中就沒有引用指向它們,但是它們的引用計數器不為0,並不會回收這些物件。這種演算法現在基本不用。。

  • 可達性分析     通過GC Root往下走,往下走的過程叫做引用鏈。當一個物件對GC Root節點沒有任何引用鏈連線的時候,這個物件就可以被回收了。     那,哪些物件可以作為GC Root嘞?

    • 虛擬機器棧(棧幀中的本地變量表)中引用的物件
    • 方法區中靜態屬性引用的物件
    • 方法區中常量引用的物件
    • 本地方法棧中引用的物件

如何回收?

  1. 回收的策略     標記清除演算法     用引用計數法或可達性分析法標記出來需要回收的物件,然後再進行清除     缺點:效率不高。記憶體空間不連續。如果有一個比較大的物件要分配記憶體就很有可能沒有連續的記憶體給它分配。     複製演算法     在熟悉複製演算法之前,先重新理一下堆。堆可以分為新生代
    老年代。新生代又可以分為Eden(伊甸園,只要有新的物件建立就會丟到伊甸園)、Survivor、Tenured Gen。 在這裡插入圖片描述     複製演算法把堆中的記憶體分為兩個部分,只用一部分。當gc的時候,將存活的物件複製到另外一半區域中,排練好。再進行回收,就能得到連續的記憶體空間。     缺點:只用一半會造成記憶體的浪費。針對記憶體浪費現在又有了新的方法,如下圖: 在這裡插入圖片描述 一般在新生代中物件的存活率為10%,超過10%物件存活就要記憶體分配擔保機制從老年代中獲取記憶體。所以這個演算法針對新生代會比較高效。     標記整理演算法     如果物件存活率較高,複製演算法的複製過程就比較耗費效能。標記整理演算法就是在標記演算法的基礎上的升級,在標記完需要回收的物件後,將存活的物件
    向一端移動,再直接清理掉邊界以外的記憶體。     分代收集演算法     根據記憶體的分代選擇不同的垃圾回收演算法,針對新生代選擇複製演算法,針對老年代選擇標記整理演算法。
  2. 常見的垃圾回收器 (有空整理各自優缺點、演算法) Serial ParNew Parallel Scavenge CMS G1

何時回收