Java虛擬機(四)--垃圾回收

垃圾回收

java基於內存的動態分配,回收也是自動且動態回收。
因java程序計數器、虛擬機棧、本地方法棧均伴隨線程產生而產生,線程銷燬而銷燬。棧幀的內存基本是類加載後肯定的,大多不考慮這部分的內存回收。
而java堆以及方法區不一樣的是,咱們只有在運行時才能知道會建立哪些對象,這部份內存是動態分配的,於是採用動態回收機制。java

分類

一、引用計數算法

給對象添加一個引用計數器,當對象被一個地方引用,則計數器加一;當引用失效時,計數器減一。當計數器爲0時,對象爲不可用,須要被清除。
缺點是兩個相互引用的對象,雖然對象已無其它引用,可是也不能被清除,GC沒法回收它們算法

二、可達性分析算法

使用GC roots 對象做爲起點,從該節點向下搜索的路徑稱爲引用鏈。當對象與GC roots之間沒有任何引用鏈相連時,該對象爲不可用。線程

能夠做爲GC roots 對象的幾種狀況:對象

  • 虛擬機棧中引用的對象
  • 方法區中常量引用的對象
  • 本地方法棧中JNI(native方法)引用的對象
  • 方法區中類靜態屬性引用的對象

引用的分類,該4中分類中引用的強弱遞減

一、強引用

是經過new 產生的對象,即Object obj = new Object(),該引用類型引用的對象永遠不會被回收。內存

二、軟引用

用於描述非必須但有用的對象,在可能發生內存溢出以前,會將對象列入回收範圍。虛擬機

三、弱引用

用於描述非必需的對象,在下次垃圾回收時,無論內存是否足夠,均會清除該類對象。效率

四、虛引用

最弱的一種引用,沒法經過虛引用獲取一個對象。垃圾回收

垃圾回收算法

一、標記清除算法
標記清除算法指「標記」和"清除」兩個過程,首先對須要回收的對象進行標記,在標記後同一回收全部被標記的對象。
這種算法會產生大量的碎片,致使須要分配較大內存時,不得不提早出發下一次垃圾回收,而且標記和清除兩個過程效率較低。搜索

二、複製算法
爲了解決標記清除算法引出的缺點,複製算法得以出現。
複製算法首先將內存一分爲二,每次只用一塊,當一塊用完了,將還須要使用的對象複製到另外一塊,而後對已使用的內存進行清理。
這樣使得內存可用範圍縮小了一半。
目前主流的虛擬機,通常講內存分爲三部分 80%的Eden和兩個較小佔10%的survivor區,這樣分佈是基於新生代98%的對象都要回收,因此每次只浪費10%的survivor區域,若是某次回收的對象超過10%,須要依賴其它內存分配擔保。引用

三、標記整理算法

當有對象存活率較高時,進行復制操做,效率會下降。針對老年代提出了另外一種算法:「標記整理」。
顧名思義,咱們先對須要清除的對象進行標記,而後對對象進行整理,使全部對象向一端移動,而後清除邊界之外的內存。

四、分代收集算法

目前商業主流虛擬機均採用該類算法,根據對象存活週期將內存區域分爲幾塊,在新生代中,對象更新較快,於是選用複製算法。老年代中,對象回收率較高,於是採用「標記-清除」或「標記-整理」算法進行回收。

相關文章
相關標籤/搜索