版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請注明出處,歡迎交流學(xué)習(xí)!

       在堆內(nèi)存中存放著Java程序中幾乎所有的對象實(shí)例,堆內(nèi)存的容量是有限的,Java虛擬機(jī)會對堆內(nèi)存進(jìn)行管理,回收已經(jīng)“死去”的對象(即不可能再被任何途徑使用的對象),釋放內(nèi)存。垃圾收集器在對堆內(nèi)存進(jìn)行回收前,首先要做的第一件事就是確定這些對象中哪些還存活著,哪些已經(jīng)死去。Java虛擬機(jī)是如何判斷對象是否可以被回收的呢?

       引用計(jì)數(shù)算法

       引用計(jì)數(shù)算法的原理是這樣的:給對象添加一個引用計(jì)數(shù)器,每當(dāng)有一個地方引用它時,計(jì)數(shù)器值就加1;當(dāng)引用失效時,計(jì)數(shù)器值就減1;在任何時刻計(jì)數(shù)器的值為0的對象就是不可能再被使用的,也就是可被回收的對象。

       引用計(jì)數(shù)算法的效率很高,但是主流的JVM并沒有選用這種算法來判定可回收對象,因?yàn)樗幸粋€致命的缺陷,那就是它無法解決對象之間相互循環(huán)引用的的問題,對于循環(huán)引用的對象它無法進(jìn)行回收。

       假設(shè)有這樣一段代碼:

       

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計(jì)培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

public class Object {    
    public Object instance;    
    public static void main(String[] args) {        
        // 1
        Object objectA = new Object();
        Object objectB = new Object();        
        // 2
        objectA.instance = objectB;
        objectB.instance = objectA;        
        // 3
        objectA = null;
        objectB = null;
        
    }

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計(jì)培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

       程序啟動后,objectA和objectB兩個對象被創(chuàng)建并在堆中分配內(nèi)存,這兩個對象都相互持有對方的引用,除此之外,這兩個對象再無任何其他引用,實(shí)際上這兩個對象已經(jīng)不可能再被訪問(引用被置空,無法訪問),但是它們因?yàn)橄嗷ヒ弥鴮Ψ剑瑢?dǎo)致它們的引用計(jì)數(shù)器都不為0,于是引用計(jì)數(shù)算法無法通知GC收集器回收它們。

       實(shí)際上,當(dāng)?shù)?步執(zhí)行時,兩個對象的引用計(jì)數(shù)器值都為1;當(dāng)?shù)?步執(zhí)行時,兩個對象的引用計(jì)數(shù)器都為2;當(dāng)?shù)?步執(zhí)行時,二者都清為空值,引用計(jì)數(shù)器值都變?yōu)?。根據(jù)引用計(jì)數(shù)算法的思想,值不為0的對象被認(rèn)為是存活的,不會被回收;而事實(shí)上這兩個對象已經(jīng)不可能再被訪問了,應(yīng)該被回收。

       可達(dá)性分析算法

       在主流的JVM實(shí)現(xiàn)中,都是通過可達(dá)性分析算法來判定對象是否存活的。可達(dá)性分析算法的基本思想是:通過一系列被稱為"GC Roots"的對象作為起始點(diǎn),從這些節(jié)點(diǎn)開始向下搜索,搜索走過的路徑稱為引用鏈,當(dāng)一個對象到GC Roots對象沒有任何引用鏈相連,就認(rèn)為GC Roots到這個對象是不可達(dá)的,判定此對象為不可用對象,可以被回收。

       photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計(jì)培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

       在上圖中,objectA、objectB、objectC是可達(dá)的,不會被回收;objectD、objectE雖然有關(guān)聯(lián),但是它們到GC Roots是不可達(dá)的,所以它們將會被判定為是可回收的對象。

       在Java中,可作為GC Roots的對象包括下面幾種:

       1、虛擬機(jī)棧中引用的對象;

       2、方法區(qū)中類靜態(tài)屬性引用的對象;

       3、方法區(qū)中常量引用的對象;

       4、本地方法棧中Native方法引用的對象。

       以上探討了判定對象是否可回收的兩種算法,判定對象是否可回收只是垃圾回收的第一步,接下來還要解決何時回收以及如何回收的問題,在后面的文章中我們來探討這些問題。

 

版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請注明出處,歡迎交流學(xué)習(xí)!

       在堆內(nèi)存中存放著Java程序中幾乎所有的對象實(shí)例,堆內(nèi)存的容量是有限的,Java虛擬機(jī)會對堆內(nèi)存進(jìn)行管理,回收已經(jīng)“死去”的對象(即不可能再被任何途徑使用的對象),釋放內(nèi)存。垃圾收集器在對堆內(nèi)存進(jìn)行回收前,首先要做的第一件事就是確定這些對象中哪些還存活著,哪些已經(jīng)死去。Java虛擬機(jī)是如何判斷對象是否可以被回收的呢?

       引用計(jì)數(shù)算法

       引用計(jì)數(shù)算法的原理是這樣的:給對象添加一個引用計(jì)數(shù)器,每當(dāng)有一個地方引用它時,計(jì)數(shù)器值就加1;當(dāng)引用失效時,計(jì)數(shù)器值就減1;在任何時刻計(jì)數(shù)器的值為0的對象就是不可能再被使用的,也就是可被回收的對象。

       引用計(jì)數(shù)算法的效率很高,但是主流的JVM并沒有選用這種算法來判定可回收對象,因?yàn)樗幸粋€致命的缺陷,那就是它無法解決對象之間相互循環(huán)引用的的問題,對于循環(huán)引用的對象它無法進(jìn)行回收。

       假設(shè)有這樣一段代碼:

       

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計(jì)培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

public class Object {    
    public Object instance;    
    public static void main(String[] args) {        
        // 1
        Object objectA = new Object();
        Object objectB = new Object();        
        // 2
        objectA.instance = objectB;
        objectB.instance = objectA;        
        // 3
        objectA = null;
        objectB = null;
        
    }

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計(jì)培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

       程序啟動后,objectA和objectB兩個對象被創(chuàng)建并在堆中分配內(nèi)存,這兩個對象都相互持有對方的引用,除此之外,這兩個對象再無任何其他引用,實(shí)際上這兩個對象已經(jīng)不可能再被訪問(引用被置空,無法訪問),但是它們因?yàn)橄嗷ヒ弥鴮Ψ?,?dǎo)致它們的引用計(jì)數(shù)器都不為0,于是引用計(jì)數(shù)算法無法通知GC收集器回收它們。

       實(shí)際上,當(dāng)?shù)?步執(zhí)行時,兩個對象的引用計(jì)數(shù)器值都為1;當(dāng)?shù)?步執(zhí)行時,兩個對象的引用計(jì)數(shù)器都為2;當(dāng)?shù)?步執(zhí)行時,二者都清為空值,引用計(jì)數(shù)器值都變?yōu)?。根據(jù)引用計(jì)數(shù)算法的思想,值不為0的對象被認(rèn)為是存活的,不會被回收;而事實(shí)上這兩個對象已經(jīng)不可能再被訪問了,應(yīng)該被回收。

       可達(dá)性分析算法

       在主流的JVM實(shí)現(xiàn)中,都是通過可達(dá)性分析算法來判定對象是否存活的??蛇_(dá)性分析算法的基本思想是:通過一系列被稱為"GC Roots"的對象作為起始點(diǎn),從這些節(jié)點(diǎn)開始向下搜索,搜索走過的路徑稱為引用鏈,當(dāng)一個對象到GC Roots對象沒有任何引用鏈相連,就認(rèn)為GC Roots到這個對象是不可達(dá)的,判定此對象為不可用對象,可以被回收。

       photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計(jì)培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

       在上圖中,objectA、objectB、objectC是可達(dá)的,不會被回收;objectD、objectE雖然有關(guān)聯(lián),但是它們到GC Roots是不可達(dá)的,所以它們將會被判定為是可回收的對象。

       在Java中,可作為GC Roots的對象包括下面幾種:

       1、虛擬機(jī)棧中引用的對象;

       2、方法區(qū)中類靜態(tài)屬性引用的對象;

       3、方法區(qū)中常量引用的對象;

       4、本地方法棧中Native方法引用的對象。

       以上探討了判定對象是否可回收的兩種算法,判定對象是否可回收只是垃圾回收的第一步,接下來還要解決何時回收以及如何回收的問題,在后面的文章中我們來探討這些問題。

 

http://www.cnblogs.com/fangfuhai/p/7197750.html