最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java怎樣判斷堆區(qū)中的對象可以被回收了

 更新時間:2024年12月25日 14:57:47   作者:高錳酸鉀_  
文章介紹了Java垃圾回收機(jī)制的工作原理,主要通過引用計數(shù)法和可達(dá)性分析法來判斷對象是否可以被回收,引用計數(shù)法存在循環(huán)引用問題,而可達(dá)性分析法則使用GCRoot對象來判斷對象是否可達(dá),從而決定是否回收,這兩種方法各有優(yōu)缺點,但Java最終采用了可達(dá)性分析法來實現(xiàn)垃圾回收

如何判斷堆區(qū)中的對象可以被回收了

在Java中,垃圾回收機(jī)制會幫助我們自動回收不再被使用的對象,已到達(dá)即使釋放內(nèi)存的效果,但是Java又是怎么知道哪些對象不會再被我們繼續(xù)使用了呢,希望你通過本篇文章,理解引用計數(shù)法與可達(dá)性分析法的運(yùn)行方式

垃圾回收機(jī)制

在C/C++中,一個對象如果不再使用,就要手動將其釋放掉,但是很多程序員在編寫程序的時候經(jīng)常忘記將一些對象回收,從而就導(dǎo)致了內(nèi)存泄漏

在Java中為了簡化對象的內(nèi)存釋放,引入了自動的垃圾回收機(jī)制,通過垃圾回收器把不再使用的對象完成自動回收,垃圾回收器主要負(fù)責(zé)堆上的內(nèi)存回收,那么垃圾回收器又是如何知道哪些對象可以被回收了呢?

在Java中,一個對象是否可以被回收,主要是看這個對象是否被引用,如果對象被引用了,說明對象還在使用,是不可以被回收的,比如說如下代碼中,堆內(nèi)存中的Demo對象被demo引用,那么堆中的Demo對象就不會被回收:

public class Demo {
    public static void main(String[] args) {
        Demo demo = new Demo();
    }
}

若此時將demo的引用設(shè)置為null:

demo = null;

那么此時Demo對象就處于了沒有被引用的狀態(tài):

此時Demo會被垃圾回收器進(jìn)行回收,那么垃圾回收器又是怎么知道Demo對象目前沒有被引用呢???

引用計數(shù)法

引用計數(shù)法會為每一個對象維護(hù)一個引用計數(shù)器,當(dāng)對象被引用時加一,取消引用時減一,在上面的代碼中,demo引用了堆上的Demo對象,所以Demo對象的引用計數(shù)器就加一,當(dāng)把demo賦值為null的時候,也就是取消了Demo的引用,此時Demo對象引用計數(shù)器將減一成為0,此時垃圾回收器就認(rèn)為Demo對象此時沒有被任何引用,可以回收

但是此時會出現(xiàn)一個問題,如果我new了兩個對象A與B,并且A對象與B對象的互為彼此的成員變量,那么就會出現(xiàn)循環(huán)引用的現(xiàn)象,此時A對象被棧內(nèi)存中的a1引用,也被B對象中的a變量引用,那么他的引用技術(shù)器應(yīng)該為2:

public class Demo {
    public static void main(String[] args) {
        A a1 = new A();
        B b1 = new B();
        a1.b = b1;
        b1.a = a1;

    }
}
class A {
    B b;
}
class B {
    A a;
}

那么此時,我取消a1、b1對A與B的引用

a1 = null;
b1 = null;

我們已經(jīng)無法在程序中獲取到A與B對象了,因為他們兩個除了彼此間的引用關(guān)系,已經(jīng)沒有任何引用能夠找到他們,所以按照常理來說,A與B對象都不會在程序中再使用了,理應(yīng)被垃圾回收器進(jìn)行回收,但是又由于存在彼此間的引用關(guān)系,引用計數(shù)器的值并不是0,那么此時垃圾回收器又會認(rèn)為A與B都存在被引用的關(guān)系,所以并不會回收這兩個類

那么這種情況顯然是不對的,無法回收的對象有可能會導(dǎo)致內(nèi)存泄漏,所以Java并沒有使用這種方法來判斷類是否應(yīng)該被回收,而是使用了另外一種方式

可達(dá)性分析法

Java使用的是可達(dá)性分析算法來判斷對象是否可以被回收

可達(dá)性分析法將對象分為兩類:

  • 垃圾回收根對象(GC Root)
  • 普通對象

對象與對象之間存在引用關(guān)系,形成一個引用鏈, 可達(dá)性分析算法就是指GC Root對象到某個對象間是可達(dá)的,即從GC Root對象開始,通過引用對象可以找到的對象愛國,即認(rèn)為該對象還不能被回收

此時B、C、D對象都可以通過引用被GC Root對象找到,即他們都是可達(dá)的,所以不會被視為可回收的對象,但是如果對象A與對象B之間取消引用關(guān)系,那么即使對象C與對象D任然存在引用關(guān)系,但他們是不可達(dá)的,因此他們會被回收

Java虛擬機(jī)會持有一個所有GC Root對象的列表,用來判斷哪些對象是不可達(dá)的,不可達(dá)的對象將被垃圾回收器進(jìn)行回收:

再次回看上面的案例,如果使用可達(dá)性分析法,那么堆內(nèi)存中應(yīng)該存在一個GC Root對象引用了主線程里面mian方法的棧幀中的對象,此時如果a1與b1不再引用堆中的對象,那么就算A對象與B對象存在引用關(guān)系,但是他們是不可達(dá)的,就會被視為等待回收的對象:

那么哪些對象可以被當(dāng)中GC Root對象呢?

主要有四種GC Root對象:

  • 1.線程Thread對象
  • 引用線程棧幀中的方法、參數(shù)、局部變量等等,上面我們的案例中就是線程Thread對象引用了mian方法棧幀中的a1與b1
  • 2.類加載器加載到的java.lang.Class對象
  • 引用類中的靜態(tài)變量
  • 3.監(jiān)視器對象
  • 用來保存同步鎖synchronized關(guān)鍵字持有的對象
  • 4.本地方法方法調(diào)用時使用的全局對象
  • 由Java虛擬機(jī)來控制調(diào)用

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java ZooKeeper分布式鎖實現(xiàn)圖解

    Java ZooKeeper分布式鎖實現(xiàn)圖解

    ZooKeeper是一個分布式的,開放源碼的分布式應(yīng)用程序協(xié)調(diào)服務(wù),是Google的Chubby一個開源的實現(xiàn),是Hadoop和Hbase的重要組件。它是一個為分布式應(yīng)用提供一致性服務(wù)的軟件,提供的功能包括:配置維護(hù)、域名服務(wù)、分布式同步、組服務(wù)等
    2022-03-03
  • Springcloud ribbon負(fù)載均衡算法實現(xiàn)

    Springcloud ribbon負(fù)載均衡算法實現(xiàn)

    這篇文章主要介紹了Springcloud ribbon負(fù)載均衡算法實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-04-04
  • java使用Hashtable過濾數(shù)組中重復(fù)值的方法

    java使用Hashtable過濾數(shù)組中重復(fù)值的方法

    這篇文章主要介紹了java使用Hashtable過濾數(shù)組中重復(fù)值的方法,涉及java數(shù)組遍歷及過濾的相關(guān)技巧,需要的朋友可以參考下
    2016-08-08
  • Core Java 簡單談?wù)凥ashSet(推薦)

    Core Java 簡單談?wù)凥ashSet(推薦)

    下面小編就為大家?guī)硪黄狢ore Java 簡單談?wù)凥ashSet(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • Java棋類游戲?qū)嵺`之單機(jī)版五子棋

    Java棋類游戲?qū)嵺`之單機(jī)版五子棋

    這篇文章主要為大家詳細(xì)介紹了Java棋類游戲中的五子棋實現(xiàn)方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-02-02
  • JAVA最容易忽視的數(shù)據(jù)類型之枚舉詳解

    JAVA最容易忽視的數(shù)據(jù)類型之枚舉詳解

    這篇文章主要給大家介紹了關(guān)于JAVA最容易忽視的數(shù)據(jù)類型之枚舉的相關(guān)資料,Java中的枚舉類型是一種特殊的類型,它允許程序員定義一個固定的值集合,并為每個值分配一個名稱,枚舉類型提供了一種簡單、安全和可讀性強(qiáng)的方式來表示一組相關(guān)的常量,需要的朋友可以參考下
    2023-10-10
  • RabbitMQ修改默認(rèn)密碼的操作步驟

    RabbitMQ修改默認(rèn)密碼的操作步驟

    這篇文章主要給大家介紹了關(guān)于RabbitMQ修改默認(rèn)密碼的操作步驟,在RabbitMQ中默認(rèn)用戶guest的密碼是guest,出于安全考慮,最好不要在生產(chǎn)環(huán)境中使用默認(rèn)用戶和密碼,需要的朋友可以參考下
    2024-11-11
  • Java如何在PPT中繪制圖形

    Java如何在PPT中繪制圖形

    這篇文章主要介紹了Java如何在PPT中繪制圖形,Microsoft PowerPoint可支持在幻燈片中插入各種類型的圖形并且可設(shè)置圖形填充、線條顏色、圖形大小、位置等。下面將通過Java編程來演示在PPT中繪制圖形的方法,需要的朋友可以參考下
    2019-07-07
  • mybatis單元測試過程(無需啟動容器)

    mybatis單元測試過程(無需啟動容器)

    在MyBatis中,單元測試無需啟動容器即可進(jìn)行,主要涉及Configuration類、Executor接口及其實現(xiàn)類,以及XMLMapperBuilder的作用,Configuration類是配置的承載者,負(fù)責(zé)初始化并解析配置文件,Executor接口及其實現(xiàn)類
    2024-09-09
  • Java實現(xiàn)文件名倒序排序的技術(shù)指南

    Java實現(xiàn)文件名倒序排序的技術(shù)指南

    在實際開發(fā)過程中,我們經(jīng)常需要對文件進(jìn)行操作和處理,一個常見的需求是按文件名倒序排列文件列表,以便于文件的管理和查找,本文將介紹如何在Java中實現(xiàn)文件名倒序排序,并提供詳細(xì)的代碼案例,需要的朋友可以參考下
    2024-08-08

最新評論

衡南县| 万山特区| 安福县| 巴东县| 东丽区| 黔江区| 望都县| 柏乡县| 宜兰县| 堆龙德庆县| 香河县| 安平县| 赞皇县| 德惠市| 夏津县| 湖口县| 望城县| 霞浦县| 五寨县| 特克斯县| 泰州市| 莱西市| 府谷县| 湘西| 临漳县| 北川| 东乡县| 定州市| 隆回县| 讷河市| 同江市| 盐边县| 桦甸市| 剑阁县| 女性| 上虞市| 莲花县| 陇川县| 岱山县| 大足县| 综艺|