Java 中的 Reference
1、強引用(StrongReference)
強引用不會被GC回收,并且在java.lang.ref里也沒有實際的對應(yīng)類型。舉個例子來說:
Object obj = new Object();
這里的obj引用便是一個強引用,不會被GC回收。
2、軟引用(SoftReference)
軟引用在JVM報告內(nèi)存不足的時候才會被GC回收,否則不會回收,正是由于這種特性軟引用在caching和pooling中用處廣泛。軟引用的用法:
Object obj = new Object(); SoftReference<Object> softRef = new SoftReference(obj); // 使用 softRef.get() 獲取軟引用所引用的對象 Object objg = softRef.get();3、弱引用(WeakReference)
當(dāng)GC一但發(fā)現(xiàn)了弱引用對象,將會釋放WeakReference所引用的對象。弱引用使用方法與軟引用類似,但回收策略不同。
4、虛引用(PhantomReference)
當(dāng)GC一但發(fā)現(xiàn)了虛引用對象,將會將PhantomReference對象插入ReferenceQueue隊列,而此時PhantomReference所指向的對象并沒有被GC回收,而是要等到ReferenceQueue被你真正的處理后才會被回收。虛引用的用法:
package com.asiainfo.proxydemo;import java.lang.ref.PhantomReference; import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; import java.lang.ref.WeakReference;public class SoftReferenceDemo {//軟引用在JVM報告內(nèi)存不足的時候才會被GC回收,否則不會回收,正是由于這種特性軟引用在caching和pooling中用處廣泛。軟引用的用法public static void soft(){Object obj = new Object();ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>();SoftReference<Object> softRef = new SoftReference<Object>(obj, refQueue);System.out.println(softRef.get()); // java.lang.Object@f9f9d8System.out.println(refQueue.poll());// null// 清除強引用,觸發(fā)GCobj = null;System.gc();System.out.println(softRef.get());try {Thread.sleep(200);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println(refQueue.poll());}//當(dāng)GC一但發(fā)現(xiàn)了弱引用對象,將會釋放WeakReference所引用的對象。弱引用使用方法與軟引用類似,但回收策略不同。public static void weak(){Object obj = new Object();ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>();WeakReference<Object> weakRef = new WeakReference<Object>(obj, refQueue);System.out.println(weakRef.get());System.out.println(refQueue.poll());obj = null;System.gc();System.out.println(weakRef.get());System.out.println(refQueue.poll());}// 如果obj被置為null,當(dāng)GC發(fā)現(xiàn)了虛引用,GC會將phanRef插入進我們之前創(chuàng)建時傳入的refQueue隊列// 注意,此時phanRef所引用的obj對象,并沒有被GC回收,在我們顯式地調(diào)用refQueue.poll返回phanRef之后// 當(dāng)GC第二次發(fā)現(xiàn)虛引用,而此時JVM將phanRef插入到refQueue會插入失敗,此時GC才會對obj進行回收public static void phantom() throws InterruptedException{Object obj = new Object();ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>();PhantomReference<Object> phanRef = new PhantomReference<Object>(obj, refQueue);/// 調(diào)用phanRef.get()不管在什么情況下會一直返回nullSystem.out.println(phanRef.get());System.out.println(refQueue.poll());obj = null;System.gc();System.out.println(phanRef.get());System.out.println(refQueue.poll());Thread.sleep(300);System.out.println(refQueue.poll());}public static void main(String[] args) {try {SoftReferenceDemo.phantom();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}} }弱引用與虛引用的用處
軟引用很明顯可以用來制作caching和pooling,而弱引用與虛引用呢?其實用處也很大,首先我們來看看弱引用,舉個例子:
class Registry {private Set registeredObjects = new HashSet();public void register(Object object) {registeredObjects.add( object );} }所有我添加進 registeredObjects 中的object永遠不會被GC回收,因為這里有個強引用保存在registeredObjects里,另一方面如果我把代碼改為如下:
class Registry {private Set registeredObjects = new HashSet();public void register(Object object) {registeredObjects.add( new WeakReference(object) );}}現(xiàn)在如果GC想要回收registeredObjects中的object,便能夠?qū)崿F(xiàn)了,同樣在使用HashMap如果想實現(xiàn)如上的效果,一種更好的實現(xiàn)是使用WeakHashMap。
而虛引用呢?我們先來看看javadoc的部分說明:
Phantom references are useful for implementing cleanup operations that are necessary before an object gets garbage-collected. They are sometimes more flexible than the?finalize()?method.
翻譯一下:
虛引用在實現(xiàn)一個對象被回收之前必須做清理操作是很有用的。有時候,他們比finalize()方法更靈活。
很明顯的,虛引用可以用來做對象被回收之前的清理工作
參考:http://www.cnblogs.com/newcj/archive/2011/05/15/2046882.html
總結(jié)
以上是生活随笔為你收集整理的Java 中的 Reference的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【剑指offer - C++/Java】
- 下一篇: OBJ 文件格式