1、概述
java內存運行時區域的各個部分,其中程序計數器、虛擬機棧、本地方法棧3個區域隨線程而生,隨線程而滅;棧中的棧幀隨着方法的進入和退出而有條不紊地執行着出棧和入棧操做。
2、對象死亡斷定
一、引用計數算法
(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;
}
}
雖然啊a,b都爲null,可是因爲存在循環引用,全部永遠不會回收。
b,浪費CPU,時刻進行計數器計數統計,即便內存夠用。
二、可達性分析算法
(1)算法:經過一系列的稱爲「GC Roots」的對象做爲起始點,從這些節點開始向下搜索,當一個對象到GC Roots沒有任何引用相連時,則證實此對象是不可用的。
注:對象object五、object六、object7雖然互有聯繫,可是它們到GC Roots不可達,因此它們被斷定爲可回收的對象。
3、垃圾收集算法
一、標記—清除算法
(1)算法想法:首先標記出全部須要回收的對象,在標記完成後統一回收全部沒有被標記的對象,若是對象在進行可達性分析後發現到GC Roots是不可達的,那麼它將會被第一次標記而且進行一次篩選,篩選條件是此對象是否有必要執行finalize()方法。當對象沒有覆蓋此方法,或者已經被虛擬機調用過,這兩種狀況都被虛擬機視爲沒有必要執行。若是有必要,那麼這個對象將會放置在F-Queue隊列之中,稍後GC將對F-Queue中的對象進行第二次小規模標記,若是對象在finalize()中成功與任何一個可達GC Roots的對象創建關聯便可,若是尚未創建關聯就將被回收。
圖示:
二、複製算法
(1)算法思想:將可用內存塊按容量劃分爲大小相等的兩塊,每次只是用其中的一塊。當這一塊的內存用完了,就將還存活着的對象複製到另一塊上面,而後再把已使用過的內存空間一次清理掉。
注:將內存分爲一塊較大的Eden空間和兩塊較小的Survivor空間,每次使用Eden和其中一塊Survivor。當回收是,將Eden和Survivor中還存活的對象一次性地複製到另外一個Survivor空間上,最後清理掉Eden和剛用過的Survivor空間。HotSpot虛擬機默認Eden和Survivor大小比例爲8:1.
(2)優勢:實現簡單,運行高效。缺點:將內存縮小爲原來一半,代價過高。
圖示:
三、標記整理算法
(1)算法思想:標記過程仍然與「標記—清除」算法同樣,但後續步驟不是直接對可回收對象進行清理,而是讓全部存活的對象都向一端移動,而後直接清理掉端邊界之外的內存。
圖示:
四、分代算法
(1)算法思想:根據對象存活週期的不一樣將內存劃分爲幾塊。通常 是把java對分爲新生代和老年代,這樣就能夠根據各個年代的特色採用最適當的收集算法。
參考文獻
【1】《深刻理解Java虛擬機》 機械工業出版社 周志明