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

Java垃圾收集之對象存活判定、回收流程與內(nèi)存策略詳解

 更新時間:2026年03月08日 10:28:07   作者:鈕祜祿愛因斯晨  
Java對象的內(nèi)存分配主要發(fā)生在堆內(nèi)存(新生代、老年代),少數(shù)情況可能分配在棧(棧上分配)或直接內(nèi)存(堆外內(nèi)存),這篇文章主要介紹了Java垃圾收集之對象存活判定、回收流程與內(nèi)存策略的相關(guān)資料,需要的朋友可以參考下

一、引言

在 Java 技術(shù)體系里,垃圾收集器(Garbage Collection,GC)與內(nèi)存分配策略是自動內(nèi)存管理的核心支撐。深入探究其原理與機(jī)制,對優(yōu)化程序內(nèi)存性能、規(guī)避內(nèi)存泄漏與溢出等問題意義重大,是理解 Java 運(yùn)行時環(huán)境的關(guān)鍵環(huán)節(jié)

二、GC 基礎(chǔ)與核心問題

(一)GC 概念溯源

垃圾收集技術(shù)并非 Java 首創(chuàng),早在 1960 年,Lisp 語言已應(yīng)用內(nèi)存動態(tài)分配與垃圾收集。GC 需解決三個核心問題:

  1. 識別待回收內(nèi)存:確定哪些對象已 “死亡”,即無被使用可能。
  2. 抉擇回收時機(jī):依據(jù)內(nèi)存使用狀況,選擇合適時機(jī)觸發(fā)回收。
  3. 選定回收方式:不同垃圾收集器采用各異的回收算法與實(shí)現(xiàn)邏輯 。

(二)對象存活判定算法

1. 引用計數(shù)算法

原理為給對象綁定引用計數(shù)器,引用建立時計數(shù)器加 1,引用失效時減 1,計數(shù)器為 0 則判定對象可回收。但存在循環(huán)引用缺陷,如代碼所示:

public class ReferenceCountingGC {
    public Object instance = null;
    private static final int _1MB = 1024 * 1024;
    private byte[] bigSize = new byte[2 * _1MB];
    public static void testGC() {
        ReferenceCountingGC objA = new ReferenceCountingGC();
        ReferenceCountingGC objB = new ReferenceCountingGC();
        objA.instance = objB;
        objB.instance = objA;
        objA = null;
        objB = null;
        System.gc();
    }
}

objAobjB相互引用,雖無實(shí)際訪問路徑,但引用計數(shù)不為 0,算法無法回收,故主流 Java 虛擬機(jī)棄用該算法。

2. 可達(dá)性分析算法

主流商用語言(如 Java、C#)采用的對象存活判定算法。以 “GC Roots” 為起始節(jié)點(diǎn)集,依據(jù)引用關(guān)系遍歷搜索,無引用鏈連接的對象判定為可回收。Java 中,GC Roots 涵蓋:

  • 虛擬機(jī)棧本地變量表引用對象,如方法內(nèi)參數(shù)、局部變量。
  • 方法區(qū)靜態(tài)屬性與常量引用對象,像類的靜態(tài)變量、字符串常量池引用。
  • 本地方法棧 JNI(Native 方法)引用對象。
  • 虛擬機(jī)內(nèi)部核心引用,包括 Class 對象、常駐異常對象(如 NullPointerException )等 。

三、引用分類及特性(JDK 1.2+)

JDK 1.2 拓展引用概念,按強(qiáng)度分為四類,各有獨(dú)特內(nèi)存管理行為:

(一)強(qiáng)引用

程序中最常見,如 Object obj = new Object() 。只要引用有效,對象不會被回收,是對象強(qiáng)存活的保障,支撐程序基本對象引用邏輯。

(二)軟引用

用于描述非必需但仍具使用價值的對象,內(nèi)存不足即將拋出溢出異常前,會觸發(fā)軟引用對象回收。通過 SoftReference 實(shí)現(xiàn),代碼示例:

SoftReference<Object> softRef = new SoftReference<>(new Object());
Object obj = softRef.get(); 

適用于緩存場景,內(nèi)存緊張時釋放非必需對象,平衡內(nèi)存使用與功能需求。

(三)弱引用

強(qiáng)度弱于軟引用,垃圾收集時,無論內(nèi)存是否充足,弱引用關(guān)聯(lián)對象都會被回收。借助 WeakReference 實(shí)現(xiàn):

WeakReference<Object> weakRef = new WeakReference<>(new Object());
Object obj = weakRef.get(); 

常用于弱關(guān)聯(lián)對象管理,如觀察者模式中臨時關(guān)聯(lián),避免因?qū)ο笕跻脤?dǎo)致內(nèi)存無法釋放。

(四)虛引用

又稱幽靈 / 幻影引用,不影響對象生命周期,也無法通過其獲取對象,主要用于接收對象回收系統(tǒng)通知,由 PhantomReference 實(shí)現(xiàn)。是內(nèi)存回收事件監(jiān)聽的特殊手段,可在對象回收時執(zhí)行特定資源清理等操作 。

四、對象回收流程與機(jī)制

對象經(jīng)可達(dá)性分析判定為不可達(dá)后,需歷經(jīng)兩次標(biāo)記才會被回收:

(一)首次標(biāo)記與篩選

對象無 GC Roots 引用鏈時,觸發(fā)首次標(biāo)記。隨后篩選是否需執(zhí)行 finalize() 方法,未重寫該方法或方法已執(zhí)行過的對象,直接判定為可回收。

(二)二次標(biāo)記與挽救

需執(zhí)行 finalize() 的對象,被移入F - Queue隊列,由 Finalizer 線程執(zhí)行該方法。若對象在 finalize() 中重新建立引用鏈(如關(guān)聯(lián)到類變量 ),二次標(biāo)記時會被移出回收隊列;否則,執(zhí)行回收。但 finalize() 存在運(yùn)行代價高、不確定性大、無法保證調(diào)用順序等問題,推薦以 try - finally 替代,示例代碼展現(xiàn)對象自我拯救過程:

public class FinalizeEscapeGC {
    public static FinalizeEscapeGC SAVE_HOOK = null;
    public void isAlive() {
        System.out.println("yes, i am still alive :)");
    }
    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("finalize method executed!");
        FinalizeEscapeGC.SAVE_HOOK = this;
    }
    public static void main(String[] args) throws Throwable {
        // 首次拯救邏輯
        SAVE_HOOK = new FinalizeEscapeGC();
        SAVE_HOOK = null;
        System.gc();
        Thread.sleep(500); 
        if (SAVE_HOOK != null) {
            SAVE_HOOK.isAlive();
        } else {
            System.out.println("no, i am dead :(");
        }
        // 二次拯救(失敗,因 finalize 僅執(zhí)行一次)
        SAVE_HOOK = null;
        System.gc();
        Thread.sleep(500); 
        if (SAVE_HOOK != null) {
            SAVE_HOOK.isAlive();
        } else {
            System.out.println("no, i am dead :(");
        }
    }
}

五、方法區(qū)的回收機(jī)制

方法區(qū)(如 HotSpot 的元空間 / 永久代 )常被誤解為無垃圾收集,實(shí)則不然,其回收聚焦以下兩部分:

(一)常量池回收

若常量池中的常量(如字符串 )無對象引用,且虛擬機(jī)無其他引用,可被回收。如字符串 “java” ,若系統(tǒng)無對應(yīng)引用,內(nèi)存回收時可能被清理,優(yōu)化常量池內(nèi)存占用。

(二)無用類回收

判定類為 “無用” 需滿足三個條件:

  1. 類及派生子類無實(shí)例,Java 堆中不存在該類相關(guān)實(shí)例。
  2. 加載該類的類加載器被回收,此條件在自定義類加載器場景中較難滿足,需精心設(shè)計。
  3. 該類對應(yīng)的 java.lang.Class 對象無引用,無法通過反射訪問類方法。

Java 虛擬機(jī)允許回收滿足條件的類,但非強(qiáng)制。在反射、動態(tài)代理等場景,需虛擬機(jī)具備類型卸載能力,可通過 -verbose:class-XX:+TraceClassLoading、-XX:+TraceClassUnLoading(部分需 FastDebug 版支持 )查看類加載 / 卸載信息,保障方法區(qū)內(nèi)存健康。

六、結(jié)論

Java 垃圾收集器與內(nèi)存分配策略,構(gòu)建起自動內(nèi)存管理的核心體系。從對象存活判定的算法演進(jìn),到引用分類的精細(xì)管控,再到對象回收流程的嚴(yán)謹(jǐn)執(zhí)行與方法區(qū)回收的特殊處理,共同保障程序內(nèi)存高效利用。深入理解該體系,是優(yōu)化程序性能、解決內(nèi)存問題的關(guān)鍵。后續(xù)將進(jìn)一步探究具體垃圾收集器(如 Serial、G1 等 )的實(shí)現(xiàn)與內(nèi)存分配策略細(xì)節(jié),持續(xù)深化 Java 內(nèi)存管理研究,為 Java 開發(fā)者筑牢技術(shù)根基,助力打造更高效、穩(wěn)定的Java應(yīng)用 。

到此這篇關(guān)于Java垃圾收集之對象存活判定、回收流程與內(nèi)存策略的文章就介紹到這了,更多相關(guān)Java對象存活判定、回收流程與內(nèi)存策略內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java 如何復(fù)制非空對象屬性值

    java 如何復(fù)制非空對象屬性值

    這篇文章主要介紹了java 如何復(fù)制非空對象屬性值的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Java多線程的臨界資源問題解決方案

    Java多線程的臨界資源問題解決方案

    這篇文章主要介紹了Java多線程的臨界資源問題解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-02-02
  • Java中使用Thread類和Runnable接口實(shí)現(xiàn)多線程的區(qū)別

    Java中使用Thread類和Runnable接口實(shí)現(xiàn)多線程的區(qū)別

    這篇文章主要介紹了使用Thread類和Runnable接口實(shí)現(xiàn)多線程的區(qū)別,本文給大家介紹了兩種實(shí)現(xiàn)方式的步驟,除了以上兩種多線程實(shí)現(xiàn)方式,還可以使用 Callable 接口實(shí)現(xiàn),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07
  • 詳解Java實(shí)現(xiàn)緩存(LRU,FIFO)

    詳解Java實(shí)現(xiàn)緩存(LRU,FIFO)

    本篇文章主要介紹了詳解Java實(shí)現(xiàn)緩存(LRU,FIFO) ,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-04-04
  • maven如何使用profiles多環(huán)境配置

    maven如何使用profiles多環(huán)境配置

    在軟件開發(fā)過程中,我們經(jīng)常需要在不同的環(huán)境中部署和運(yùn)行我們的應(yīng)用程序,例如開發(fā)環(huán)境、測試環(huán)境和生產(chǎn)環(huán)境,為了方便管理和配置不同環(huán)境下的參數(shù),我們可以使用Maven的profiles功能,本文給大家介紹maven如何使用profiles多環(huán)境配置,感興趣的的朋友一起看看吧
    2024-02-02
  • IDEA中使用jclasslib插件可視化方式查看類字節(jié)碼的過程詳解

    IDEA中使用jclasslib插件可視化方式查看類字節(jié)碼的過程詳解

    查看JAVA字節(jié)碼有兩種方式一種是使用 jdk命令 javap,還有一種就是 使用 插件了,今天給大家分享IDEA中使用jclasslib插件可視化方式查看類字節(jié)碼的過程詳解,感興趣的朋友跟隨小編一起看看吧
    2021-05-05
  • Java實(shí)現(xiàn)格式化打印慢SQL日志的方法詳解

    Java實(shí)現(xiàn)格式化打印慢SQL日志的方法詳解

    不管我們使用何種語言開發(fā),一旦程序發(fā)生異常,日志是一個很重要的數(shù)據(jù),下面這篇文章主要給大家介紹了關(guān)于Java實(shí)現(xiàn)格式化打印慢SQL日志的相關(guān)資料,需要的朋友可以參考下
    2022-10-10
  • Java中字符串拼接的一些細(xì)節(jié)分析

    Java中字符串拼接的一些細(xì)節(jié)分析

    這篇文章主要介紹了Java中字符串拼接的一些細(xì)節(jié)分析,本文著重剖析了字符串拼接的一些性能問題、技巧等內(nèi)容,需要的朋友可以參考下
    2015-01-01
  • 詳解spring注解式參數(shù)校驗(yàn)

    詳解spring注解式參數(shù)校驗(yàn)

    本篇文章主要介紹了詳解spring注解式參數(shù)校驗(yàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • JAVA中AES加密方法實(shí)例分析

    JAVA中AES加密方法實(shí)例分析

    這篇文章主要介紹了JAVA中AES加密方法,實(shí)例分析了java中AES加密與解密的實(shí)現(xiàn)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-07-07

最新評論

梅州市| 加查县| 东阳市| 遂溪县| 雅安市| 云阳县| 偃师市| 罗源县| 武清区| 微博| 山阳县| 通化市| 东辽县| 宁陕县| 资兴市| 肇州县| 德令哈市| 搜索| 梧州市| 台安县| 红河县| 诸暨市| 镇坪县| 胶南市| 盐池县| 沂源县| 甘洛县| 甘南县| 忻城县| 井冈山市| 读书| 新乡市| 新竹市| 融水| 黎城县| 山东省| 普安县| 鄂伦春自治旗| 淳安县| 开封市| 吉首市|