JVM---對象是否存活及被引用的狀態

1.如何判斷對象是否存活

1.1 引用計數算法

????????概念:在對象頭部增加一個引用計數器,每當有一個地方引用它時,計數器值就加一;當引用失效時,計數器值就減一;任何時刻計數器為零的對象就是不可能再被使用的。

????????優點:速度快,高效

????????缺點: 假如此時A引用B,B引用A那么,計數永遠不為0,那么永遠無法回收他們

1.2 可達性分析算法:

????????概念:通過一系列稱為“GC Roots”的根對象作為起始節點集,從這些節點開始,根據引用關系向下搜索,搜索過程所走過的路徑稱為“引用鏈”(Reference Chain),如果某個對象到GC Roots間沒有任何引用鏈相連,或者用圖論的話來說就是從GC Roots到這個對象不可達時,則證明此對象是不可能再被使用的。

? ? ? ?總結概念: 也就是找到是否連接根節點,此時如果A引用B,B引用A就不會發生,循環回收不掉的問題,因為他們找不到連接的根節點,也是當前主流的判斷對象是否存活的算法

????????注意:即使在可達性分析算法中判定為不可達的對象,也不是“非死不可”的,這時候它們暫時還處于“緩刑”階段,要真正宣告一個對象死亡,至少要經歷兩次標記過程:如果對象在進行可達性分析后發現沒有與GC Roots相連接的引用鏈,那它將會被第一次標記,隨后進行一次篩選,篩選的條件是此對象是否有必要執行finalize()方法。

2.再談引用

????????無論是通過引用計數算法判斷對象的引用數量,還是通過可達性分析算法判斷對象是否引用鏈可 達,判定對象是否存活都和“ 引用 離不開關系。
????????在JDK 1.2 版之前, Java 里面的引用是很傳統的定義: 如果reference 類型的數據中存儲的數值代表的是另外一塊內存的起始地址,就稱該 reference 數據是代表 某塊內存、某個對象的引用。這種定義并沒有什么不對,只是現在看來有些過于狹隘了,一個對象在 這種定義下只有“ 被引用 或者 未被引用 兩種狀態,對于描述一些 食之無味,棄之可惜 的對象就顯 得無能為力。
????????譬如我們希望能描述一類對象:當內存空間還足夠時,能保留在內存之中,如果內存空
間在進行垃圾收集后仍然非常緊張,那就可以拋棄這些對象 —— 很多系統的緩存功能都符合這樣的應用場景。
? ? ? ? 所以在JDK 1.2版之后,Java對引用的概念進行了擴充,引入了四種引用

3.四種引用

2.1? 強引用

????????是最傳統的“引用”的定義,是指在程序代碼之中普遍存在的引用賦值,即類似“Object obj=new Object()”這種引用關系。無論任何情況下,只要強引用關系還存在,垃圾收集器就永遠不會回收掉被引用的對象。

2.2 軟引用

????????是用來描述一些還有用,但非必須的對象。只被軟引用關聯著的對象,在系統將要發生內存溢出異常前,會把這些對象列進回收范圍之中進行第二次回收,如果這次回收還沒有足夠的內存,才會拋出內存溢出異常。在JDK 1.2版之后提供了SoftReference類來實現軟引用。

2.3 弱引用

????????也是用來描述那些非必須對象,但是它的強度比軟引用更弱一些,被弱引用關聯的對象只能生存到下一次垃圾收集發生為止。當垃圾收集器開始工作,無論當前內存是否足夠,都會回收掉只被弱引用關聯的對象。在JDK 1.2版之后提供了WeakReference類來實現弱引用。

2.4 虛引用

????????也稱為“幽靈引用”或者“幻影引用”,它是最弱的一種引用關系。一個對象是否有虛引用的存在,完全不會對其生存時間構成影響,也無法通過虛引用來取得一個對象實例。為一個對象設置虛引用關聯的唯一目的只是為了能在這個對象被收集器回收時收到一個系統通知。在JDK 1.2版之后提供了PhantomReference類來實現虛引用。

3. 軟引用的進一步了解

3.1 軟引用的使用場景

?????????軟引用主要用于實現內存敏感的高速緩存。當系統內存充足時,軟引用的對象可以長時間駐留在內存中,供程序快速訪問;當系統內存不足時,這些對象可以被垃圾回收器回收,從而避免內存溢出錯誤。這種機制非常適合用于緩存系統,如圖片緩存、頁面緩存等。

3.2 為什么用到了軟引用

  1. 內存壓力下的靈活應對:軟引用允許JVM在內存緊張時自動回收對象,從而避免了程序因為內存不足而崩潰的風險。

  2. 提高性能:通過保留軟引用對象,在內存充足時可以直接訪問這些對象,減少了重新加載或重新計算這些對象所需的時間和資源。

  3. 資源管理的靈活性:開發者可以通過軟引用來控制緩存的大小和生命周期,而不是完全依賴于JVM的垃圾回收機制。

3.3 軟引用的使用(小例子)

import java.lang.ref.SoftReference;  public class SoftReferenceExample {  public static void main(String[] args) {  // 假設這是我們需要緩存的數據  Object data = new Object();  // 創建一個軟引用指向這個數據  SoftReference<Object> softRef = new SoftReference<>(data);  // 使用softRef.get()來獲取軟引用指向的對象  Object cachedData = softRef.get();  // 模擬內存緊張的情況(實際上在簡單示例中無法直接模擬)  // 在實際環境中,當JVM進行垃圾回收時,如果內存不足,可能會回收softRef指向的對象  // 再次嘗試獲取對象,如果對象已被回收,則返回null  cachedData = softRef.get();  if (cachedData != null) {  // 對象仍然存在,可以繼續使用  } else {  // 對象已被回收,需要重新加載或重新計算  }  }  
}

注意:由于垃圾回收的時機和過程是由JVM的垃圾回收器控制的,因此我們不能精確地預測軟引用對象何時會被回收。在實際應用中,開發者需要根據應用的內存需求和性能要求來合理使用軟引用。

4. 弱引用的進一步了解

4.1 使用場景

  1. 緩存系統
    • 在一些緩存系統中,特別是當緩存的數據量很大且不是必需時,可以使用弱引用來引用這些數據。這樣,當JVM內存不足時,這些數據可以被自動回收,從而避免內存溢出。
    • 例如,WeakHashMap就是基于弱引用實現的,它允許鍵值對中的鍵是弱引用的。這意味著,如果某個鍵除了被WeakHashMap所引用外,沒有其他強引用指向它,那么這個鍵以及它所對應的值都可能被垃圾回收器回收。
  2. 生命周期較短的臨時對象
    • 對于那些生命周期較短,且對內存敏感的臨時對象,可以使用弱引用來引用它們。這樣,一旦這些對象不再被其他強引用所指向,它們就可以被垃圾回收器及時回收。

4.2?為什么用到了弱引用

  1. 內存管理的靈活性
    • 弱引用提供了一種比軟引用更加靈活的內存管理方式。通過弱引用,開發者可以更加精確地控制對象的生命周期,避免內存泄漏,同時也能夠確保在內存不足時能夠自動回收非必需的對象。
  2. 減少內存泄漏的風險
    • 在一些復雜的應用程序中,由于對象之間的引用關系錯綜復雜,很容易出現內存泄漏的情況。通過使用弱引用,可以減少因為對象之間的強引用關系而導致的內存泄漏風險。
  3. 提升性能
    • 在一些性能敏感的應用程序中,及時回收不再使用的對象可以釋放更多的內存空間,從而提升應用程序的性能。弱引用通過自動回收非必需的對象,有助于減少內存占用,提升性能。

4.3 弱引用的使用(小例子)

import java.lang.ref.WeakReference;  public class WeakReferenceExample {  public static void main(String[] args) {  // 創建一個強引用對象  Object strongRef = new Object();  // 創建一個弱引用對象,指向強引用對象  WeakReference<Object> weakRef = new WeakReference<>(strongRef);  // 驗證弱引用是否有效  System.out.println(weakRef.get()); // 輸出對象地址  // 將強引用置為null,模擬對象不再被強引用  strongRef = null;  // 觸發垃圾回收(注意:實際環境中,垃圾回收的時機是不確定的)  System.gc();  // 再次驗證弱引用是否有效  // 由于強引用已被置為null,且沒有其他強引用指向該對象,因此該對象可能會被垃圾回收  // 此時,weakRef.get()可能返回null  System.out.println(weakRef.get()); // 可能輸出null  }  
}

同樣和弱引用相同:由于垃圾回收的時機和過程是由JVM的垃圾回收器控制的,因此我們不能精確地預測弱引用對象何時會被回收。在實際應用中,開發者需要根據應用的內存需求和性能要求來合理使用弱引用。

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

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

相關文章

vue2遷移到vue3注意點

vue2遷移到vue3注意點 1、插槽的修改 使用 #default &#xff0c; 以及加上template 模板 2、 類型的定義&#xff0c;以及路由&#xff0c;vue相關資源&#xff08;ref, reactive,watch&#xff09;的引入等 3、類裝飾器 1&#xff09;vue-class-component是vue官方庫,作…

ubuntu搭建harbor私倉

1、環境準備 鏈接: https://pan.baidu.com/s/1q4XBWPd8WdyEn4l253mpUw 提取碼: 7ekx --來自百度網盤超級會員v2的分享 準備一臺Ubuntu 機器:192.168.124.165 將上面兩個文件考入Ubuntu上面 2、安裝harbor 安裝Docker Harbor倉庫以容器方式運行,需要先安裝好docker,參考:…

詳解python基本語法

文章目錄 數據變量數據結構 循環-判斷-用戶輸入判斷用戶輸入循環 函數參數返回值將函數存儲在模塊中 文件和異常讀取文件異常操作Json文件 類對象創建類使用類類的繼承導入外部類 測試測試函數創建測試 Python 是一種廣泛使用的高級編程語言&#xff0c;以其清晰的語法和代碼可…

which 命令在Linux中是一個快速查找可執行文件位置的工具

文章目錄 0、概念1、which --help2、which命令解釋 0、概念 which命令用于查找命令的可執行文件的路徑which 命令在 Linux 中用于查找可執行命令的完整路徑。當你在 shell 中輸入一個命令時&#xff0c;shell 會在環境變量 $PATH 定義的目錄列表中查找這個命令。which 命令可以…

React基礎學習-Day06

React基礎學習-Day06 zustand基本使用方式 1.基礎使用 基本使用 zustand 的步驟包括創建狀態存儲和在組件中使用這些狀態和更新函數。以下是一個基礎的示例&#xff0c;演示如何使用 zustand 來管理一個簡單的計數器狀態。 安裝 首先&#xff0c;確保你的項目中已經安裝了…

socket編程(2) -- TCP通信

TCP通信 2. 使用 Socket 進行TCP通信2.1 socket相關函數介紹socket()bind()listen()accept()connect()2.2 TCP協議 C/S 模型基礎通信代碼 最后 2. 使用 Socket 進行TCP通信 Socket通信流程圖如下&#xff1a; 這里服務器段listen是監聽socket套接字的監聽文件描述符。如果客戶…

Redis--布隆過濾器

解決緩存穿透是構建高效緩存系統中的關鍵問題之一。緩存穿透指的是惡意或者非法請求經過緩存層直接訪問數據庫或者后端服務&#xff0c;導致系統資源浪費和性能下降的情況。為了有效應對緩存穿透問題&#xff0c;以下是幾種常見的解決方法&#xff1a; 1. 布隆過濾器預檢查 布…

運維-Docker-黑馬

運維-Docker-黑馬 編輯時間&#xff1a;2024/7/15 來源&#xff1a;黑馬程序員 docker&#xff1a;快速構建&#xff0c;運行&#xff0c;管理應用的工具 Docker安裝 部署mysql 命令解讀

[Cesium for Supermap] 加載3dTiles,點擊獲取屬性

代碼&#xff1a; // 設為橢球var obj [6378137.0, 6378137.0, 6356752.3142451793];Cesium.Ellipsoid.WGS84 Object.freeze(new Cesium.Ellipsoid(obj[0], obj[1], obj[2]));var viewer new Cesium.Viewer(cesiumContainer);var scene viewer.scenescene.lightSource.ambi…

Oracle TDE(Transparent Data Encryption) 常見問題解答 - 官網

此FAQ來源于官網鏈接。此為新版&#xff0c;老版的博客參見Oracle TDE(Transparent Data Encryption) 常見問題解答。 通用問題 透明數據加密 (TDE) 提供什么功能&#xff1f; TDE 以透明方式加密 Oracle 數據庫中的靜態數據。它可以阻止操作系統未經授權嘗試訪問存儲在文件…

徹底改變時尚:使用 GAN 實現 AI 的未來

徹底改變時尚&#xff1a;使用 GAN 實現 AI 的未來 一、介紹 想象一下&#xff0c;在這個世界里&#xff0c;時裝設計師永遠不會用完新想法&#xff0c;我們穿的每一件衣服都是一件藝術品。聽起來很有趣&#xff0c;對吧&#xff1f;好吧&#xff0c;我們可以在通用對抗網絡 &a…

鴻蒙基本工程目錄

工程級目錄 AppScope 中存放應用全局所需要的資源文件。entry 是應用的主模塊&#xff0c;存放 HarmonyOS 應用的代碼、資源等。oh_modules 是工程的依賴包&#xff0c;存放工程依賴的源文件。build-profile.json5 是工程級配置信息&#xff0c;包括簽名、產品配置等。hvigorf…

品牌產業出海指南如何搭建國際化架構的跨境電商平臺?

在“品牌&產業出海指南 – 成功搭建跨境電商平臺”系列中&#xff0c;我們將從電商分銷系統、跨境平臺商城/多商戶商城系統和國際化架構三個方面對幫助您梳理不同平臺模式的優缺點、應用場景、開發重點和運營建議。 在“品牌&產業出海指南 – 成功搭建跨境電商平臺”系…

【漏洞復現】Rejetto HTTP文件服務器——遠程命令執行(CVE-2024-23692)

聲明&#xff1a;本文檔或演示材料僅供教育和教學目的使用&#xff0c;任何個人或組織使用本文檔中的信息進行非法活動&#xff0c;均與本文檔的作者或發布者無關。 文章目錄 漏洞描述漏洞復現測試工具 漏洞描述 Rejetto HTTP文件服務器是一個輕量級的HTTP服務器軟件&#xff…

VBA學習(20):一批簡單的Excel VBA編程問題解答

1.如何確定單元格區域內的行數和列數&#xff1f; 使用Range.Rows.Count和Range.Columns.Count屬性。 2.Application.Columns指的是什么&#xff1f; 活動工作表中的列。 3.你的程序在列B位置插入一個新列&#xff0c;原來的列B會怎樣&#xff1f; 它向右移動成為列C。 4.假…

vue項目1分鐘實現自定義右鍵菜單,懶人的福音

高效實現需求&#xff0c;避免重復造輪子&#xff0c;今天給大家分享的是&#xff0c;如何在最短的時間內實現右鍵菜單&#xff0c;方法也很簡單&#xff0c;一個插件就可以搞定&#xff0c;話不多說&#xff0c;上效果圖&#xff1a; 1. 效果圖&#xff1a; 2. 安裝&#xff…

5. 基于Embedding實現超越elasticsearch高級搜索

Embedding介紹 Embedding是向量的意思&#xff0c;向量可以理解為平面坐標中的一個坐標點(x,y),在編程領域&#xff0c;一個二維向量就是一個大小為float類型的數組。也可以用三維坐標系中的向量表示一個空間中的點。在機器學習中&#xff0c;向量通常用于表示數據的特征。 向量…

SCI丨中三區

無線網絡遙感圖像和視頻處理技術在xxxxx析基于智能物聯網的xxxxx養老模式可持續發展基于心理行為大數據分類算法xxxxxx研究基于云計算xxxxx行為分析及客戶感知體系的構建基于機器學習的xxxxx金鋼時效行為研究 基于機器視覺的xxxxx檢測系統研究 機器學習的電子顯微鏡xxxxx材料的…

探索Laravel的視圖組件與插槽:構建動態且可復用的UI

探索Laravel的視圖組件與插槽&#xff1a;構建動態且可復用的UI 引言 Laravel作為一個現代化的PHP框架&#xff0c;提供了許多強大的功能來幫助開發者構建高性能和可維護的Web應用。其中&#xff0c;視圖組件&#xff08;View Components&#xff09;和插槽&#xff08;Slots…

【React Hooks原理 - forwardRef、useImperativeHandle】

概述 上文我們聊了useRef的使用和實現&#xff0c;主要兩個用途&#xff1a;1、用于持久化保存 2、用于綁定dom。 但是有時候我們需要在父組件中訪問子組件的dom或者屬性/方法&#xff0c;而React中默認是不允許父組件直接訪問子組件的dom的&#xff0c;這時候就可以通過forwa…