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