Java中常用的四種引用類(lèi)型詳解
GC 回收的優(yōu)先級(jí)上: 強(qiáng)引用 -> 軟引用 -> 弱引用 -> 虛引用
1.強(qiáng)引用
當(dāng)內(nèi)存不足,JVM
開(kāi)始進(jìn)行 gc
時(shí),對(duì)于強(qiáng)引用的對(duì)象不會(huì)進(jìn)行回收,即使出現(xiàn)了OOM
也不會(huì)回收。因此,強(qiáng)引用是造成內(nèi)存泄露的主要原因。
class MyObject { @Override protected void finalize() throws Throwable{ //finalize 通常目的是在某個(gè)對(duì)象內(nèi)存被gc之前執(zhí)行的操作 System.out.println("------------invoke finalize method~~~"); } } public class ReferenceDemo{ public static void main(String[] args) throws InterruptedException{ // 1. 強(qiáng)引用 --- 一定不會(huì)被 GC直至拋出OOM MyObject myObject = new MyObject(); System.out.println("-----gc before\t" + myObject); System.gc(); System.out.println("-----gc after\t " + myObject); } } // -----gc before ThreadLocal.MyObject@6aaa5eb0 // -----gc after ThreadLocal.MyObject@6aaa5eb0
2.軟引用
當(dāng)進(jìn)行GC
時(shí),如果內(nèi)存還足夠,則不進(jìn)行回收該對(duì)象,若內(nèi)存不夠,則回收該對(duì)象內(nèi)存空間
class MyObject { @Override protected void finalize() throws Throwable{ //finalize 通常目的是在某個(gè)對(duì)象內(nèi)存被gc之前執(zhí)行的操作 System.out.println("------------invoke finalize method~~~"); } } public class ReferenceDemo{ public static void main(String[] args) throws InterruptedException { //2. 軟引用 --- 內(nèi)存夠用: 不會(huì)被GC || 內(nèi)存不夠用: 會(huì)被GC SoftReference<MyObject> reference = new SoftReference<>(new MyObject()); // 通過(guò) get() 方法返回真實(shí)對(duì)象 System.out.println("-----gc before: "+reference .get()); System.gc(); Thread.sleep(100); System.out.println("-----gc after: " + reference .get()); } } //-----gc before: ThreadLocal.MyObject@6aaa5eb0 //-----gc after: ThreadLocal.MyObject@6aaa5eb0
3. 弱引用
當(dāng) JVM
開(kāi)始 gc
時(shí),無(wú)論內(nèi)存是否還足夠,對(duì)于若引用對(duì)象都要進(jìn)行回收
class MyObject { @Override protected void finalize() throws Throwable{ //finalize 通常目的是在某個(gè)對(duì)象內(nèi)存被gc之前執(zhí)行的操作 System.out.println("------------invoke finalize method~~~"); } } public class ReferenceDemo{ public static void main(String[] args) throws InterruptedException{ //3. 弱引用 --- 只要JVM 一開(kāi)始GC, 不管內(nèi)存是否足夠, 該內(nèi)存區(qū)域都會(huì)被回收 WeakReference<MyObject> weakReference = new WeakReference<>(new MyObject()); System.out.println("內(nèi)存夠用,before gc: "+weakReference.get()); System.gc(); System.out.println("內(nèi)存夠用,after gc: "+weakReference.get()); } } // 內(nèi)存夠用,before gc: ThreadLocal.MyObject@3498ed // ------------invoke finalize method~~~ // 內(nèi)存夠用,after gc: null
4.虛引用
虛引用必須與 ReferenceQueue
一起使用,當(dāng) gc
準(zhǔn)備回收一個(gè)對(duì)象,如果發(fā)現(xiàn)它還有虛引用,就會(huì)在回收之前,把這個(gè)虛引用加入到與之關(guān)聯(lián)的 ReferenceQueue
中
class MyObject { @Override protected void finalize() throws Throwable{ //finalize 通常目的是在某個(gè)對(duì)象內(nèi)存被gc之前執(zhí)行的操作 System.out.println("------------invoke finalize method~~~"); } } public class ReferenceDemo{ public static void main(String[] args) throws InterruptedException{ // 4. 虛引用: 必須要和引用隊(duì)列一起使用, get()方法永遠(yuǎn)返回null PhantomReference<MyObject> reference = new PhantomReference<>(new MyObject(),new ReferenceQueue<>()); // 無(wú)法返回引用對(duì)象 System.out.println(reference .get()); // 當(dāng)被回收后, 該對(duì)象會(huì)進(jìn)入引用隊(duì)列 ReferenceQueue System.gc(); Thread.sleep(200); if(reference .enqueue()){ System.out.println("----------有虛對(duì)象被回收"); } } } // null // ------------invoke finalize method~~~ // ----------有虛對(duì)象被回收
到此這篇關(guān)于Java中常用的四種引用類(lèi)型詳解的文章就介紹到這了,更多相關(guān)Java引用類(lèi)型內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
如何解決SpringBoot 加入AOP后無(wú)法注入的問(wèn)題
這篇文章主要介紹了如何解決SpringBoot 加入AOP后無(wú)法注入的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06mybatis QueryWrapper的條件構(gòu)造之a(chǎn)pply、last、select解析
這篇文章主要介紹了mybatis QueryWrapper的條件構(gòu)造之a(chǎn)pply、last、select,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03Spring Cache + Caffeine的整合與使用示例詳解
對(duì)于一些項(xiàng)目里需要對(duì)數(shù)據(jù)庫(kù)里的某些數(shù)據(jù)一直重復(fù)請(qǐng)求的,且這些數(shù)據(jù)基本是固定的,在這種情況下,可以借助簡(jiǎn)單使用本地緩存來(lái)緩存這些數(shù)據(jù),本文介紹一下Spring Cache和Caffeine的使用,感興趣的朋友一起看看吧2023-12-12IDEA最新版2020.1的maven工程本地依賴(lài)倉(cāng)庫(kù)無(wú)法使用問(wèn)題(已解決)
這篇文章主要介紹了IDEA最新版2020.1的maven工程本地依賴(lài)倉(cāng)庫(kù)無(wú)法使用問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06HTTPClient如何在Springboot中封裝工具類(lèi)
這篇文章主要介紹了HTTPClient如何在Springboot中封裝工具類(lèi)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09Spring3 整合MyBatis3 配置多數(shù)據(jù)源動(dòng)態(tài)選擇SqlSessionFactory詳細(xì)教程
這篇文章主要介紹了Spring3 整合MyBatis3 配置多數(shù)據(jù)源動(dòng)態(tài)選擇SqlSessionFactory詳細(xì)教程,需要的朋友可以參考下2017-04-04java字符串?dāng)?shù)字補(bǔ)齊位數(shù)詳解
這篇文章主要介紹了java字符串?dāng)?shù)字補(bǔ)齊位數(shù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-03-03