1. 程式人生 > >java虛擬機器垃圾回收演算法

java虛擬機器垃圾回收演算法

引用計數法:

原理:對於物件A,只要任意的物件引用了A,則A的引用計數器加一。當引用失效時,引用計數器減一。引用計數器的值為0時,物件A不可使用,回收。

缺點:1.無法處理迴圈問題。如果A引用了B,B同時引用了A。但A,B都不被其他任何物件引用。那麼A,B都是不可達的。那麼A,B不會被回收,從而引起記憶體洩漏。(java中未使用)

標記清除法:

原理:將垃圾回收分為兩個階段:標記階段,清除階段。

       標記階段:從根節點出發,標記所有可達的物件。

       清除階段:將所有未被標記的物件清除。

缺點:空間碎片問題。被清除的記憶體不是連續的。不連續的記憶體空間的效率低於連續的空間。

複製演算法

原理:將原有的記憶體空間分為兩塊,一次只使用其中的一塊。垃圾回收時,將正在使用的存活物件複製到未使用的記憶體塊中,清除正在使用的記憶體塊中的所有物件,交換兩個記憶體的角色完成垃圾回收。

缺點:內存摺半,單純的複製演算法難以接受。

適用於新生代。新生代垃圾物件多於存活物件。

標記壓縮法

原理:在標記清除法的基礎上進行改進。從根節點開始對所有可達物件進行標記,將所有存活物件壓縮到記憶體的一端,清理邊界外的所有空間。

優點:價效比高,無空間碎片,不需要兩塊相等的空間。

適用於:老年代

分代演算法

原理:各種垃圾回收演算法中沒有一個可以完全替代其他演算法,每一個都有其獨特的優勢和特點。因此,根據垃圾回收物件的特點對不同種類的物件使用不同的演算法。

       新生代物件:具有早生夕死的特點,大約90%的新建物件會很快被回收。適用複製演算法

       老年代物件:經過幾次回收仍然存活,存活率較高。使用標記清除法或標記壓縮法。

卡表:用於對應新生代和老年代的引用關係。新生代回收頻率很高但耗時很短,老年代頻率低,但耗時長。如果回收新生代時每次都要驗證新生代物件是否被老年代物件引用會大大降低效率。卡表就是為了提高新生代的高頻率回收的資料結構。卡表為一個位元位集合,每一個位元位表示老年代的某一個區域的所有物件是否持有新生代物件的引用。這樣新生代GC時就不用花費大量時間掃描老年代物件。只有當卡表標記位為1時才需掃描。

分割槽演算法

原理:

將堆空間分為不同的小區間。每一個小區間都獨立使用,獨立回收。可以一次控制回收多個小區間。垃圾回收時會產生停頓現象,停頓時整個應用程式會被卡死,沒有任何響應。每次回收若干個小區間,而不是整個堆空間,可以靈活的控制停頓時間減少一次GC產生的停頓。