java中强引用、弱引用、软引用、虚引用学习
文章目錄
- 強引用
- 弱引用
- 軟引用
- 虛引用
將引用之前首先讓我們一起回顧一下
java對象的生命周期
強引用
在實際開發場景中,我們一般使用的都是強引用,只要強引用存在,垃圾回收即使OOM也不會回收,知道強引用釋放以后,對象才會被釋放掉,可以顯示地將引用賦值為null,這樣的話,JVM會在合適的時間回收該對象。
以下是測試:
public void method() {Object o = new Object();Object[] os = new Object[800000];System.out.println(os.length);}@Testpublic void srongReference(){method();}在method方法沒有結束之前,method中定義的局部變量的對象是不會被回收,method結束后會在適合GC。
回收測試:
@Testpublic void strongReference() throws InterruptedException {Thread.sleep(40 * 1000);System.out.println("加載");method();Object o = new Object();Object[] os = new Object[800000];System.out.println("判斷是否回收");Thread.sleep(20 * 1000);o = null;os = null;System.gc();System.out.println("強制回收");Thread.sleep(100 * 1000);}通過 jconsole監控內存變化,發現當強引用關系解除以后,強制GC的時候,對象會被回收掉!!!
弱引用
引用是用來描述非必須對象的,當JVM進行垃圾回收時候,無論內存是否充足,都會回收。
@Testpublic void weakReference() { // ArrayList<Person> ps = new ArrayList<>();//list存儲的對象引用也是強引用關系 // ps.add(person);WeakReference<Object> wf = new WeakReference<>(new Person("weijie", 25));System.out.println(wf.get());System.out.println(wf.isEnqueued());System.gc();System.out.println(wf.get());System.out.println(wf.isEnqueued());}
由控制臺輸可以看出,只要是弱引用,只要發生GC對象會被回收。
由上可看出由于list導致對象存在強引用關系,此時加上弱引用的話對象也不會被回收,需要手動將person=null 接觸強引用關系以后,對象才會GC時候回收
軟引用
用來描述一些有用但并不是必須的對象,對于軟引用關聯的對象,只有在內存不足的時候JVM才會回收該對象,這一點可以很好解決OOM問題,這個特性很適合用來實現緩存:網頁緩存、圖片緩存等。
軟引用可以和一個引用隊列(ReferenceQueue)聯合使用,如果軟引用所引用的對象被JVM回收,這個軟引用就會被加入到與之關聯的引用隊列中。
虛引用
虛引用:垃圾回收時回收,無法通過引用取到對象值PhantomReference 唯一的用處就是跟蹤 referent 何時被 enqueue(入隊列) 到 ReferenceQueue 中虛引用主要用來跟蹤對象被垃圾回收的活動。
虛引用必須和引用隊列關聯使用,當垃圾回收器準備回收一個對象時,如果發現它還有虛引用,就會把這個虛引用加入到與之 關聯的引用隊列中。程序可以通過判斷引用隊列中是否已經加入了虛引用, 來了解被引用的對象是否將要被垃圾回收。如果程序發現某個虛引用已經被加入到引用隊列, 那么就可以在所引用的對象的內存被回收之前采取必要的行動。
@Testpublic void phantomReference(){Person person = new Person("weijie", 24);ReferenceQueue<Person> referenceQueue = new ReferenceQueue<Person>();PhantomReference<Person> personPhantomReference = new PhantomReference<Person>(person, referenceQueue);System.out.println(referenceQueue.poll());System.out.println(personPhantomReference.get());//判斷對象是否被標記回收System.out.println(personPhantomReference.enqueue());person = null;System.out.println(personPhantomReference.get());System.out.println(personPhantomReference.enqueue());}
虛引用打印的值永遠為null,唯一用處就是顯示enqueue(入隊列)
總結
以上是生活随笔為你收集整理的java中强引用、弱引用、软引用、虚引用学习的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ACM训练总结(大二)
- 下一篇: java多线程爬虫框架crawler4j