判斷對象是否可回收和垃圾收集算法

一、判斷對象是否可以被回收的算法。
1.引用計數算法(Reference Counting):
給對象中添加一個引用計數器,每當有一個地方引用它時,計數器值就加1;
當引用失效時,計數器值就減1;
任何時刻計數器爲0的對象就是不可能再被使用的。
主流的虛擬機都沒有使用該算法,很難解決對象之間相互循環引用的問題。

2.可達性分析算法策略(Reachability Analysis)
這個算法的基本思路就是通過一系列的稱爲“GC Roots”的對象作爲起始點,
從這些節點開始向下搜索,搜索所走過的路徑稱爲引用鏈(Reference Chain),當一個對象到GC Roots沒有任何引用鏈相連
(用圖論的話來說,就是從GC Roots到這個對象不可達)時,則證明此對象是不可用的。
可以作爲GC Roots對象:
1)虛擬機棧中,引用的對象
2)方法區中,類靜態屬性引用的對象
3)方法區中,常量引用的對象
4)本地方法棧中,Native方法引用的對象

引用:
1)在JDK 1.2以前,Java中的引用的定義很傳統:如果reference類型的數據中存儲的數值代表的是另外一塊內存的起始地址,就稱這塊內存代表着一個引用。
2)強引用就是指在程序代碼之中普遍存在的,類似“Object obj=new Object()”這類的引用,只要強引用還存在,垃圾收集器永遠不會回收掉被引用的對象。
3)軟引用是用來描述一些還有用但並非必需的對象。
4)弱引用也是用來描述非必需對象的,但是它的強度比軟引用更弱一些,被弱引用關聯的對象只能生存到下一次垃圾收集發生之前。
5)虛引用也稱爲幽靈引用或者幻影引用,它是最弱的一種引用關係。

二、垃圾收集器算法
1.標記-清除算法
標記需要回收的對象,在標記完成後,統一回收所有的標記對象。
弊端:效率問題(標記清除的效率都不高),空間問題(產生大量的空間碎片)
2.複製算法(大多數虛擬機用這種算法)
將內存分爲大小相等的兩塊,每次只使用其中的一塊,當內存需要回收,將活着的對象複製到另一內存,清除整塊的內存。解決了碎片化的問題。
可以按照9:1的比例劃分,只有10%的內存浪費,但是需要額外的空間進行分配擔保。
S0和S1區就是使用這個算法。
3.標記-整理算法
標記過程仍然與“標記-清除”算法一樣,但後續步驟不是直接對可回收對象進行清理,而是讓所有存活的對象都向一端移動,
然後直接清理掉端邊界以外的內存
4.分代收集算法
當前商業虛擬機的垃圾收集都採用“分代收集”(Generational Collection)算法,這種算法並沒有什麼新的思想,
只是根據對象存活週期的不同將內存劃分爲幾塊。 一般是把Java堆分爲新生代和老年代,
這樣就可以根據各個年代的特點採用最適當的收集算法。 在新生代中,每次垃圾收集時都發現有大批對象死去,只有少量存活,
那就選用複製算法,只需要付出少量存活對象的複製成本就可以完成收集。 而老年代中因爲對象存活率高、 沒有額外空間
對它進行分配擔保,就必須使用“標記—清理”或者“標記—整理”算法來進行回收。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章