java垃圾收集相關問題
阿新 • • 發佈:2017-06-10
算法 如果 ring 沒有 roo 可用 nal 一個 空間
(2)缺點 a,很難解決對象之間相互循環引用的問題。如下:
(1)算法:通過一系列的稱為“GC Roots”的對象作為起始點,從這些節點開始向下搜索,當一個對象到GC Roots沒有任何引用相連時,則證明此對象是不可用的。
一、概述
java內存運行時區域的各個部分,其中程序計數器、虛擬機棧、本地方法棧3個區域隨線程而生,隨線程而滅;棧中的棧幀隨著方法的進入和退出而有條不紊地執行著出棧和入棧操作。二、對象死亡判定
1、引用計數算法 (1)判定算法:給對象中添加一個引用計數器,每當一個地方引用它時,計數器值就加1;當引用失效時,計數器值就減1;任何時刻計數器為0的對象就是不能再被使用的。(2)缺點 a,很難解決對象之間相互循環引用的問題。如下:
class TestA{
public TestB b;
}
class TestB{
public TestA a;
}
public class Main{
public static void main(String[] args){
A a = new A();
B b = new B();
a.b=b;
b.a=a;
a = null;
b = null;
}
}
註:對象object5、object6、object7雖然互有聯系,但是它們到GC Roots不可達,所以它們被判定為可回收的對象。
三、垃圾收集算法
1、標記—清除算法 (1)算法想法:首先標記出所有需要回收的對象,在標記完成後統一回收所有沒有被標記的對象,如果對象在進行可達性分析後發現到GC Roots是不可達的,那麽它將會被第一次標記並且進行一次篩選,篩選條件是此對象是否有必要執行finalize()方法。當對象沒有覆蓋此方法,或者已經被虛擬機調用過,這兩種情況都被虛擬機視為沒有必要執行。如果有必要,那麽這個對象將會放置在F-Queue隊列之中,稍後GC將對F-Queue中的對象進行第二次小規模標記,如果對象在finalize()中成功與任何一個可達GC Roots的對象建立關聯即可,如果還沒有建立關聯就將被回收。 圖示:2、復制算法 (1)算法思想:將可用內存塊按容量劃分為大小相等的兩塊,每次只是用其中的一塊。當這一塊的內存用完了,就將還存活著的對象復制到另外一塊上面,然後再把已使用過的內存空間一次清理掉。 註:將內存分為一塊較大的Eden空間和兩塊較小的Survivor空間,每次使用Eden和其中一塊Survivor。當回收是,將Eden和Survivor中還存活的對象一次性地復制到另一個Survivor空間上,最後清理掉Eden和剛用過的Survivor空間。HotSpot虛擬機默認Eden和Survivor大小比例為8:1. (2)優點:實現簡單,運行高效。缺點:將內存縮小為原來一半,代價太高。 圖示:
3、標記整理算法 (1)算法思想:標記過程仍然與“標記—清除”算法一樣,但後續步驟不是直接對可回收對象進行清理,而是讓所有存活的對象都向一端移動,然後直接清理掉端邊界以外的內存。 圖示:
4、分代算法 (1)算法思想:根據對象存活周期的不同將內存劃分為幾塊。一般 是把java對分為新生代和老年代,這樣就可以根據各個年代的特點采用最適當的收集算法。 參考文獻 【1】《深入理解Java虛擬機》 機械工業出版社 周誌明
java垃圾收集相關問題