JVM 垃圾回收器是如何判斷一個對象是否要回收?

JVM 垃圾回收器(Garbage Collector)需要判斷哪些對象是“垃圾”,即不再被程序使用的對象,以便回收它們占用的內存。JVM 主要使用以下兩種方法來判斷對象是否是垃圾:

1. 引用計數算法 (Reference Counting):

  • 原理:

    • 為每個對象維護一個引用計數器。
    • 當一個對象被引用時,引用計數器加 1。
    • 當一個對象的引用被置為 null 或超出作用域時,引用計數器減 1。
    • 當一個對象的引用計數器為 0 時,表示該對象不再被任何地方引用,可以被回收。
  • 優點:

    • 實現簡單: 只需要維護一個計數器。
    • 實時性高: 當對象的引用計數器變為 0 時,可以立即回收該對象。
  • 缺點:

    • 無法解決循環引用問題: 如果兩個或多個對象相互引用,即使它們不再被其他對象引用,它們的引用計數器也不會變為 0,導致無法回收。
    public class ReferenceCountingGC {public Object instance = null;public static void main(String[] args) {ReferenceCountingGC objA = new ReferenceCountingGC();ReferenceCountingGC objB = new ReferenceCountingGC();objA.instance = objB; // objA 引用 objBobjB.instance = objA; // objB 引用 objAobjA = null; // objA 不再引用對象objB = null; // objB 不再引用對象// 此時,objA 和 objB 相互引用,引用計數器都不為 0,無法被回收 (即使它們已不再被使用)// ...}
    }
    
  • HotSpot VM 是否使用: HotSpot VM 不使用引用計數算法,因為它無法解決循環引用問題。

2. 可達性分析算法 (Reachability Analysis) (根搜索算法):

  • 原理:

    • 從一組稱為 “GC Roots” 的根對象開始,沿著對象引用鏈進行遍歷。
    • 如果一個對象到 GC Roots 之間沒有任何引用鏈相連,則說明該對象不可達,可以被回收。
    • 可達的對象會被標記, 不可達的對象被認為是垃圾.
  • GC Roots:

    • 虛擬機棧 (VM Stack) 中引用的對象: 局部變量、方法參數等引用的對象。
    • 方法區中類靜態屬性引用的對象: static 變量引用的對象。
    • 方法區中常量引用的對象: final 修飾的常量引用的對象。
    • 本地方法棧中 JNI (Java Native Interface) 引用的對象: Native 方法引用的對象。
    • Java 虛擬機內部的引用: 例如, 基本數據類型對應的 Class 對象, 一些常駐的異常對象(NullPointerException, OutOfMemoryError 等), 系統類加載器.
    • 被同步鎖 (synchronized 關鍵字) 持有的對象。
    • 反應Java虛擬機內部情況的 JMXBean、JVMTI 中注冊的回調、本地代碼緩存等。
  • 優點:

    • 可以解決循環引用問題。
    • 準確性高。
  • 缺點:

    • 需要暫停應用程序 (Stop-The-World): 在進行可達性分析時,需要暫停所有 Java 線程,以保證分析結果的準確性。
    • 實現復雜。
  • HotSpot VM 是否使用: HotSpot VM 使用可達性分析算法

對象死亡的判定 :

即使通過可達性分析算法判斷一個對象不可達,它也不會立即被回收。對象真正死亡需要經歷至少兩次標記過程:

  1. 第一次標記:

    • 如果對象在進行可達性分析后發現沒有與 GC Roots 相連接的引用鏈,則會被第一次標記。
    • 會進行篩選, 判斷此對象是否有必要執行 finalize() 方法。
    • 如果對象沒有覆蓋 finalize() 方法,或者 finalize() 方法已經被虛擬機調用過,則會被判定為“沒有必要執行”。
    • 如果對象覆蓋了 finalize() 方法, 且還沒有被調用過, 則會將該對象放置在一個名為 F-Queue 的隊列中。
  2. finalize() 方法的執行 (如果有):

    • 稍后由一條由虛擬機自動建立的、低調度優先級的 Finalizer 線程去執行它們的 finalize() 方法。
    • 注意:
      • finalize() 方法是對象逃脫死亡的最后一次機會。
      • finalize() 方法中,只要將對象重新與引用鏈上的任何一個對象建立關聯(例如,將 this 賦值給某個類變量或對象的成員變量),就可以避免被回收。
      • finalize() 方法只會被系統自動調用一次。如果對象在 finalize() 方法中逃脫了死亡,下次再被標記時,finalize() 方法不會再被執行。
      • 不建議使用 finalize() 方法進行資源釋放,因為它的執行時間不確定,可能會導致資源長時間得不到釋放。
      • finalize 方法可能會導致性能問題,應盡量避免使用。
  3. 第二次標記:

    • 如果在 finalize() 方法中對象成功逃脫了死亡,則不會被回收。
    • 如果在 finalize() 方法中對象沒有逃脫死亡,或者對象沒有覆蓋 finalize() 方法,或者 finalize() 方法已經被虛擬機調用過,則會被第二次標記。
    • 被第二次標記的對象會被放置在一個名為 F-Queue 的隊列中, 等待被回收.

總結:

JVM 使用可達性分析算法來判斷對象是否是垃圾。從 GC Roots 開始,沿著對象引用鏈進行遍歷,如果一個對象到 GC Roots 之間沒有任何引用鏈相連,則說明該對象不可達,可以被回收。即使對象不可達,也不會立即被回收,需要經歷至少兩次標記過程,并且有機會在 finalize() 方法中逃脫死亡。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/75734.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/75734.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/75734.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

kali——httrack

目錄 前言 使用教程 前言 HTTrack 是一款運行于 Kali Linux 系統中的開源網站鏡像工具,它能將網站的頁面、圖片、鏈接等資源完整地下載到本地,構建出一個和原網站結構相似的離線副本。 使用教程 apt install httrack //安裝httrack工具 httrac…

kotlin函數類型

一 函數類型定義 1 定義 函數類型就是 (Int, Int) -> Int 函數類型其實就是將函數的 “參數類型” 和 “返回值類型” 抽象出來 2 示例 : (Int, Int) -> Int 表示接收兩個 Int 參數并返回 Int 的函數類型; (String) -> Unit 表示接收 Strin…

C# Winform 入門(9)之如何封裝并調用dll

封裝dll 首先創建 .Net平臺 類庫 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace _09.Encapsulation_dll {public class Program{/// <summary>/// 求兩個double類型的數值的和/// &l…

前后端分離下,Spring Boot 請求從發起到響應的完整執行流程

以下是前后端分離架構下&#xff0c;Spring Boot 請求從發起到響應的完整執行流程&#xff0c;結合你提出的所有問題&#xff0c;按真實執行順序和職責鏈條重新整理所有核心概念、結構、關鍵類、數據轉換點和典型代碼示例&#xff1a; 一、前端發起請求&#xff08;步驟1-2&…

基于sklearn實現文本摘要思考

和各位小伙伴分享一下使用sklearn進行文本摘要的思考。 第一版本 原理 提取式文本摘要的基本原理是&#xff1a; 將文本分割成句子 計算每個句子的重要性(權重) 選擇權重最高的幾個句子組成摘要 常用的句子權重計算方法&#xff1a; TF-IDF&#xff1a;基于詞頻-逆文檔頻…

OpenHarmony子系統開發 - DFX(三)

OpenHarmony子系統開發 - DFX&#xff08;三&#xff09; 五、HiTraceMeter開發指導 HiTraceMeter概述 簡介 HiTraceMeter在OpenHarmony中&#xff0c;為開發者提供業務流程調用鏈跟蹤的維測接口。通過使用該接口所提供的功能&#xff0c;可以幫助開發者迅速獲取指定業務流…

2025年 能夠有效提升AI的生成質量和邏輯嚴謹性 的通用型系統提示

以下是三個經過精心設計的通用型系統提示&#xff08;System Prompt&#xff09;&#xff0c;能夠有效提升AI的生成質量和邏輯嚴謹性&#xff0c;適用于各類對話、分析和創作場景&#xff1a; Prompt 1 - 專家級分步驗證模式 你是一個具備跨領域知識整合能力的超級AI&#xff…

python爬蟲:小程序逆向實戰教程

根據我之前發表的文章&#xff0c;我們進行延伸實戰https://blog.csdn.net/weixin_64809364/article/details/146981598?spm1001.2014.3001.5501 1. 想要爬取什么小程序&#xff0c;我們進行搜索 2. 找到我們vx小程序的文件地址&#xff0c;我們就可以進行破解 破解步驟強看…

C語言變長數組(VLA)詳解:靈活處理動態數據的利器

引言 在C語言中&#xff0c;傳統的數組大小必須在編譯時確定&#xff0c;這限制了程序處理動態數據的靈活性。C99標準引入的變長數組&#xff08;Variable-Length Array, VLA&#xff09; 打破了這一限制&#xff0c;允許數組長度在運行時動態確定。本文將深入解析VLA的語法、…

串口數據轉換為IP數據

串口數據轉換為IP數據是一種常見的通信技術,用于將傳統的串行設備(如傳感器、控制器等)接入現代的IP網絡。以下是詳細介紹: 1. 轉換原理 串口數據轉換為IP數據的過程涉及硬件和軟件的結合,核心是將串行數據封裝為TCP/IP或UDP/IP數據包,通過網絡傳輸。具體步驟如下: 硬…

client-go如何監聽自定義資源

如何使用 client-go 監聽自定義資源 在 Kubernetes 中使用 client-go 監聽自定義資源&#xff08;Custom Resource&#xff0c;簡稱 CR&#xff09;需要借助 Dynamic Client 或 Custom Informer&#xff0c;因為 client-go 的標準 Clientset 只支持內置資源&#xff08;如 Pod…

C++軟件開發架構

文章目錄 1.全局消息通信MsgHandler.h單元測試(QTest)MsgHandlerUnitTest.hMsgHandlerUnitTest.cpp 2.實例間通信InstMsgHandler.h單元測試InstMsgHandlerUnitTest.hInstMsgHandlerUnitTest.cpp 1.全局消息通信 1. 適用于類與類單個對象實例之間的通信&#xff0c;多個對象需要…

AI Agent設計模式一:Chain

概念 &#xff1a;線性任務流設計 ? 優點&#xff1a;邏輯清晰易調試&#xff0c;適合線性處理流程? 缺點&#xff1a;缺乏動態分支能力 from typing import TypedDictfrom langgraph.graph import StateGraph, END# 定義后續用到的一些變量 class CustomState(TypedDict):p…

Git三劍客:工作區、暫存區、版本庫深度解析

一、引言&#xff1a;為什么需要理解Git的核心區域&#xff1f; 作為開發者&#xff0c;Git是日常必備的版本控制工具。但你是否曾因以下問題感到困惑&#xff1f; 修改了文件&#xff0c;但 git status 顯示一片混亂&#xff1f; git add 和 git commit 到底做了什么&#x…

Python數據類型-list

列表(List)是Python中最常用的數據類型之一&#xff0c;它是一個有序、可變的元素集合。 1. 列表基礎 創建列表 empty_list [] # 空列表 numbers [1, 2, 3, 4, 5] # 數字列表 fruits [apple, banana, orange] # 字符串列表 mixed [1, hello, 3.14, True] # 混合類型…

Keepalive+LVS+Nginx+NFS高可用項目

項目架構 分析 主機規劃 主機系統安裝應用網絡IPclientredhat 9.5無NAT172.25.250.115/24lvs-masterrocky 9.5ipvsadm&#xff0c;keepalivedNAT172.25.250.116/24 VIP 172.25.250.100/32lvs-backuprocky 9.5ipvsadm&#xff0c;keepalivedNAT172.25.250.117/24 VIP 172.25.2…

【視覺與語言模型參數解耦】為什么?方案?

一些無編碼器的MLLMs統一架構如Fuyu&#xff0c;直接在LLM內處理原始像素&#xff0c;消除了對外部視覺模型的依賴。但是面臨視覺與語言模態沖突的挑戰&#xff0c;導致訓練不穩定和災難性遺忘等問題。解決方案則是通過參數解耦方法解決模態沖突。 在多模態大語言模型&#xf…

AI比人腦更強,因為被植入思維模型【43】蝴蝶效應思維模型

giszz的理解&#xff1a;蝴蝶效應我們都熟知&#xff0c;就是說一個微小的變化&#xff0c;能帶動整個系統甚至系統的空間和時間的遠端&#xff0c;產生巨大的鏈式反應。我學習后的啟迪&#xff0c;簡單的說&#xff0c;就是不要忽視任何微小的問題&#xff0c;更多時候&#x…

AI 數理邏輯基礎之統計學基本原理(上)

目錄 文章目錄 目錄統計學統計學基本概念描述性統計數據可視化圖表工具 匯總統計統計數據的分布情況&#xff1a;中位數、眾數、平均值統計數據的離散程度&#xff1a;極差、方差、標準差、離散系數 相關分析Pearson 線性關系相關系數Spearman 單調關系相關系數 回歸分析回歸模…

無招回歸阿里

這兩天&#xff0c;無招回歸阿里的新聞被刷屏了。無招創業成立的兩氫一氧公司無招的股份也被阿里收購&#xff0c;無招以這種姿態回歸阿里&#xff0c;并且出任釘釘的 CEO。有人說&#xff0c;這是對 5 年前“云釘一體”戰略的糾偏。現在確實從云優先到 AI 優先&#xff0c;但云…