Java的四大引用詳解-沖擊金三銀四

強引用

? ? 像“Object obj = new Object()”這類的引用均為強引用,當一個對象被強引用變量引用時,它處于可達狀態,是不可能被垃圾回收器回收的,即使該對象永遠不會被用到也不會被回收。

? ? 當JVM出現內存不足時,JVM進行垃圾回收,對于強引用的對象,就算是出現了 OOM 也不會對該對象進行回收,打死都不收。因此強引用有時也是造成 Java 內存泄露的原因之一。如果將其引用賦值為null,一般認為是可以被垃圾回收掉的。(具體回收時間還要看使用的GC策略)

? ? 示例代碼:

public class StrongRefenenceDemo {public static void main(String[] args) {Object o1 = new Object();Object o2 = o1;o1 = null;System.gc();System.out.println(o1);  //nullSystem.out.println(o2);  //java.lang.Object@2503dbd3}
}

軟引用

?? ?軟引用是一種相對強引用弱化了一些的引用,需要用java.lang.ref.SoftReference 類來實現,可以讓對象豁免一些垃圾收集。

?? ?軟引用用來描述一些還有用,但并非必需的對象。

? ? 對于只有軟引用的對象:當系統內存充足時它不會被回收,當系統內存不足時它才會被回收。

//VM options: -Xms5m -Xmx5m
public class SoftRefenenceDemo {public static void main(String[] args) {softRefMemoryEnough();System.out.println("------內存不夠用的情況------");softRefMemoryNotEnough();}private static void softRefMemoryEnough() {Object o1 = new Object();SoftReference<Object> s1 = new SoftReference<Object>(o1);System.out.println(o1);System.out.println(s1.get());o1 = null;System.gc();System.out.println(o1);System.out.println(s1.get());}/*** JVM配置`-Xms5m -Xmx5m` ,然后故意new一個一個大對象,使內存不足產生 OOM,看軟引用回收情況*/private static void softRefMemoryNotEnough() {Object o1 = new Object();SoftReference<Object> s1 = new SoftReference<Object>(o1);System.out.println(o1);System.out.println(s1.get());o1 = null;byte[] bytes = new byte[10 * 1024 * 1024];System.out.println(o1);System.out.println(s1.get());}
}

輸出結果:

--------------------------------------輸出結果-------------------------------------------------
java.lang.Object@2503dbd3
java.lang.Object@2503dbd3
null
java.lang.Object@2503dbd3
------內存不夠用的情況------
java.lang.Object@4b67cf4d
java.lang.Object@4b67cf4d
java.lang.OutOfMemoryError: Java heap space
at reference.SoftRefenenceDemo.softRefMemoryNotEnough(SoftRefenenceDemo.java:42)
at reference.SoftRefenenceDemo.main(SoftRefenenceDemo.java:15)
null
null

弱引用

?? ?弱引用也是用來描述非必需對象的,但是它的強度比軟引用更弱一些,被弱引用關聯的對象只能生存到下一次垃圾收集發生之前。當垃圾收集器工作時,無論當前內存是否足夠,都會回收掉只被弱引用關聯的對象。

?? ?弱引用需要用java.lang.ref.WeakReference類來實現,它比軟引用的生存期更短。

public class WeakReferenceDemo {public static void main(String[] args) {Object o1 = new Object();WeakReference<Object> w1 = new WeakReference<Object>(o1);System.out.println(o1);System.out.println(w1.get());o1 = null;System.gc();System.out.println(o1);//均被回收System.out.println(w1.get());//均被回收}
}

關于WeakHashMap示例代碼

public class WeakHashDemo {public static void main(String[] args) throws InterruptedException  {myHashMap();System.out.println("-----------------------------------------------");myWeakHashMap();}public static void myHashMap() {HashMap<String, String> map = new HashMap<String, String>();String key = new String("k1");String value = "v1";map.put(key, value);System.out.println(map);key = null;System.gc();System.out.println(map);}public static void myWeakHashMap() throws InterruptedException {WeakHashMap<String, String> map = new WeakHashMap<String,  String>();// String key = "weak";// 剛開始寫成了上邊的代碼// 思考一下,寫成上邊那樣會怎么樣?那可不是引用了String key = new String("weak");String value = "map";map.put(key, value);System.out.println(map);// 去掉強引用key = null;System.gc();Thread.sleep(1000);System.out.println(map);}
}
----------------------------------輸出結果--------------------------------------------
{k1=v1}
{k1=v1}
-----------------------------------------------
{weak=map}
{}

?

虛引用

?? ?虛引用也稱為“幽靈引用”或者“幻影引用”,它是最弱的一種引用關系。虛引用需要java.lang.ref.PhantomReference 來實現。

?? ?虛引用需要java.lang.ref.PhantomReference 來實現。

?? ?如果一個對象僅持有虛引用,那么它就和沒有任何引用一樣,在任何時候都可能被垃圾回收器回收,它不能單獨使用也不能通過它訪問對象,虛引用必須和引用隊列(RefenenceQueue)聯合使用。

?? ?虛引用的主要作用是跟蹤對象垃圾回收的狀態。僅僅是提供了一種確保對象被 finalize 以后,做某些事情的機制。

?? ?PhantomReference 的 get 方法總是返回 null,因此無法訪問對應的引用對象。其意義在于說明一個對象已經進入 finalization 階段,可以被 GC 回收,用來實現比 finalization 機制更靈活的回收操作。

?? ?設置虛引用的唯一目的,就是在這個對象被回收器回收的時候收到一個系統通知或者后續添加進一步的處理。

?

public class PhantomReferenceDemo {public static void main(String[] args) throws InterruptedException {Object o1 = new Object();ReferenceQueue<Object> referenceQueue = new ReferenceQueue<Object>();PhantomReference<Object> phantomReference = new PhantomReference<Object>(o1,referenceQueue);System.out.println(o1);System.out.println(referenceQueue.poll());System.out.println(phantomReference.get());o1 = null;System.gc();Thread.sleep(3000);System.out.println(o1);System.out.println(referenceQueue.poll()); //引用隊列中System.out.println(phantomReference.get());}}
-------------------------------------------------------------------------------------------------------
java.lang.Object@4554617c
null
null
null
java.lang.ref.PhantomReference@74a14482
null

引用隊列

?? ?ReferenceQueue 是用來配合引用工作的,沒有ReferenceQueue 一樣可以運行。

?? ?SoftReference、WeakReference、PhantomReference 都有一個可以傳遞 ReferenceQueue 的構造器。

?? ?創建引用的時候,可以指定關聯的隊列,當 GC 釋放對象內存的時候,會將引用加入到引用隊列。如果程序發現某個虛引用已經被加入到引用隊列,那么就可以在所引用的對象的內存被回收之前采取必要的行動,這相當于是一種通知機制。

圖片

Reference的四種狀態:

  • Active:新創建的引用實例處于Active狀態,但當GC檢測到該實例引用的實際對象的可達性發生某些改變(實際對象處于 GC roots 不可達)后,它的狀態將變化為Pending或者Inactive。如果 Reference 注冊了ReferenceQueue,則會切換為Pending,并且Reference會加入pending-Reference鏈表中,如果沒有注冊ReferenceQueue,會切換為Inactive。

  • Pending:當引用實例被放置在pending-Reference 鏈表中時,它處于Pending狀態。此時,該實例在等待一個叫Reference-handler的線程將此實例進行enqueue操作。如果某個引用實例沒有注冊在一個引用隊列中,該實例將永遠不會進入Pending狀態。

  • Enqueued:在ReferenceQueue隊列中的Reference的狀態,如果Reference從隊列中移除,會進入Inactive狀態。

  • Inactive:一旦某個引用實例處于Inactive狀態,它的狀態將不再會發生改變,同時說明該引用實例所指向的實際對象一定會被GC所回收。

圖片

?想要了解更多技術文章請關注公眾號“職谷智享”,每天關注的前50名小伙伴可領取200+互聯網相關技術書籍。

?

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

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

相關文章

繼承-重寫

Phone基類&#xff1a; package ven;public class Phone {public Phone(){}public void call(String name){System.out.println("給"name"打電話");} } AIPhone子類&#xff1a; package ven;public class AIPhone extends Phone{Override //重載注解&am…

mTLS: openssl創建CA證書

證書可以通過openssl或者keytool創建&#xff0c;在本篇文章中&#xff0c;只介紹openssl。 openssl 生成證書 申請操作流程 生成ca證書私鑰, 文件名&#xff1a;ca.key生成ca證書&#xff0c;文件名&#xff1a;ca.crt生成Server/Client 證書私鑰&#xff0c;文件名&#x…

設計模式(十三)抽象工廠模式

請直接看原文:設計模式&#xff08;十三&#xff09;抽象工廠模式_抽象工廠模式告訴我們,要針對接口而不是實現進行設計。( )-CSDN博客 -------------------------------------------------------------------------------------------------------------------------------- …

系統架構設計文檔模版

XX 系統架構設計方案 修訂記錄 日期 版本號 修訂說明 修訂人 審核人 1、概述... 5 1.1&#xff0e;業務背景... 5 1.2&#xff0e;系統總體描述... 5 1.3&#xff0e;系統邊界圖... 5 1.4&#xff0e;名詞和縮略語... 5 1.…

live555源碼學習(1)

1 基礎組件 live項目主要包含了四個基礎庫、程序入口類&#xff08;mediaServer&#xff09;和測試程序&#xff08;testProgs&#xff09;。四個基礎庫是UsageEnvironment、BasicUsageEnvironment、groupsock和liveMedia UsageEnvironment 抽象了兩個類UsageEnvironment和T…

力扣hot5---雙指針

題目&#xff1a; 解決方案&#xff1a;雙指針 指針 i 指向最左側&#xff0c;指針 j 指向最右側。此時在寬度上達到了最大值&#xff0c;那么哪個柱子更矮&#xff0c;哪個柱子向內部移動&#xff0c;知道 i 與 j 相遇。為什么呢&#xff1f; 如果哪個哪個柱子更矮&#xff0c…

代碼隨想錄算法訓練營第四十一天|198.打家劫舍,213.打家劫舍II,337.打家劫舍III

系列文章目錄 代碼隨想錄算法訓練營第一天|數組理論基礎&#xff0c;704. 二分查找&#xff0c;27. 移除元素 代碼隨想錄算法訓練營第二天|977.有序數組的平方 &#xff0c;209.長度最小的子數組 &#xff0c;59.螺旋矩陣II 代碼隨想錄算法訓練營第三天|鏈表理論基礎&#xff…

Node.js基礎---模塊化

基本概念 模塊化 模塊化是指解決一個復雜問題時&#xff0c;自上向下逐層把系統劃分成若干模塊的過程&#xff0c;對于整個系統來說&#xff0c;模塊是可組合&#xff0c;分解和更換的單元 遵守固定規則&#xff0c;把大文件拆分成獨立并互相依賴的多個小模塊 好處&#xff1a…

【計算機畢業設計】208基于SSM的在線教育網站

&#x1f64a;作者簡介&#xff1a;擁有多年開發工作經驗&#xff0c;分享技術代碼幫助學生學習&#xff0c;獨立完成自己的項目或者畢業設計。 代碼可以私聊博主獲取。&#x1f339;贈送計算機畢業設計600個選題excel文件&#xff0c;幫助大學選題。贈送開題報告模板&#xff…

OLLAMA:如何像專業人士一樣運行本地語言模型

原文 https://cheatsheet.md/llm-leaderboard/ollama.en簡介&#xff1a;揭示 OLLAMA 對本地語言模型的強大功能 您是否曾經發現自己陷入了基于云的語言模型網絡中&#xff0c;渴望獲得更本地化、更具成本效益的解決方案&#xff1f;好吧&#xff0c;您的搜索到此結束。歡迎來…

逆向案例四、進階,爬取精靈數據咨詢前五十頁數據

python代碼示例: import csv import execjs import requests f open(精靈數據.csv,w,encodingutf-8,newline) csv_writer csv.DictWriter(f,fieldnames[標題,發布時間,新聞來源,詳情頁鏈接,轉自,點擊量,新聞作者,發布時間小時,]) csv_writer.writeheader() data [] for pa…

【Ansys Fluent Web 】全新用戶界面支持訪問大規模多GPU CFD仿真

基于Web的技術將釋放云計算的強大功能&#xff0c;加速CFD仿真&#xff0c;從而減少對硬件資源的依賴。 主要亮點 ? 使用Ansys Fluent Web用戶界面?&#xff08;UI&#xff09;&#xff0c;用戶可通過任何設備與云端運行的仿真進行遠程交互 ? 該界面通過利用多GPU和云計算功…

理解python3中的回調函數

百度百科說&#xff1a;回調函數就是一個通過函數指針調用的函數。如果你把函數的指針&#xff08;地址&#xff09;作為參數傳遞給另一個函數&#xff0c;當這個指針被用來調用其所指向的函數時&#xff0c;我們就說這是回調函數。回調函數不是由該函數的實現方直接調用&#…

Sqli-labs靶場第13關詳解[Sqli-labs-less-13]

Sqli-labs-Less-13 #手工注入 post傳參了 根據題目看&#xff0c;像一個登錄頁面&#xff0c;嘗試使用布爾型盲注測試能否登錄網站 1. Username輸入a 測試是否會有報錯&#xff0c;burp抓包 報錯&#xff1a;syntax to use near a) and password() LIMIT 0,1 at line 1 分…

[python] `json.dumps()` TypeError: Object of type set is not JSON serializable

在Python中&#xff0c;當你嘗試將一個集合&#xff08;set&#xff09;類型的對象轉換為JSON格式時&#xff0c;可能會遇到“TypeError: Object of type set is not JSON serializable”的錯誤。這是因為標準的JSON格式不支持Python中的集合類型&#xff0c;JSON格式支持的數據…

【04】C語言括號匹配問題

歡迎來到土土的博客~&#x1f973;&#x1f973;&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;個人主頁&#xff1a;大耳朵土土垚的博客 &#x1f4a5; 所屬專欄&#xff1a;C語言系列函數實現 題目描述&#xff1a; 給定一個只包括 ‘(’&#xff0c;‘)’&#xf…

加密隧道技術

在現在的互聯網上傳輸數據&#xff0c;首要考慮的就是安全。這關乎到你的隱私&#xff0c;個人信息&#xff0c;財產安全等等重大問題。如果你的程序本身傳輸的信息沒有加密&#xff0c;也可以通過其他輔助方式讓你的通信加密。一些工具的就是為了解決這樣的場景的&#xff0c;…

之前續寫抖音開發者接入字節小游戲的緩存一下,現在說一下在 Windows 或者 Mac 如何用終端更換路徑?

window: 比方說你的 window 目錄下是這個路徑: 第一:E:\project\Q1\trunk\client\src,然后你想切換到下一個路徑的話,你可以這樣子操作: 第二:E:\project\Q1\trunk\client\src> cd .\usersetting 然后回車,這里不會計較大小寫 第三:你就可以在這個目錄下執行你的腳本:E:…

學習大數據,所必需的java基礎(7)

文章目錄 File類File 的靜態成員File的構造方法File的獲取方法相對路徑和絕對路徑File的創建方法File類中的刪除方法File的遍歷方法 字節流IO流介紹以及輸入輸出以及流向的介紹IO流的流向IO流分類IO流分類 OutputStream中的子類FileOutoutStream的介紹以及方法的簡單介紹InputS…

服務器中如何檢查端口是否開放

有多種方法可以檢測服務器端口是否開放。以下是一些常用的方法&#xff1a; 1. Telnet 命令&#xff1a; 使用 Telnet 命令來測試端口的可達性。在命令提示符或終端中執行以下命令&#xff1a; telnet your_server_ip your_port_number 如果連接成功&#xff0c;表示端口是…