Java中的四大引用(強引用,弱引用,軟引用,虛引用)

引用這個概念經常被提及,今天總結一下。

強引用

強引用即(StrongReference)我們最常使用的引用,A a=new A()。這個a就是一個強引用。


軟引用

即(SoftReference),


Object obj = new Object();
SoftReference<Object> sf = new SoftReference<Object>(obj);
obj = null;
sf.get();//有時候會返回null

弱引用

即(WeakReference

Object obj = new Object();
WeakReference<Object> wf = new WeakReference<Object>(obj);
obj = null;
wf.get();//有時候會返回null
wf.isEnQueued();//返回是否被垃圾回收器標記爲即將回收的垃圾

虛引用

即(PhantomReference

Object obj = new Object();
PhantomReference<Object> pf = new PhantomReference<Object>(obj);
obj=null;
pf.get();//永遠返回null
pf.isEnQueued();//返回是否從內存中已經刪除


引用的作用

強引用就不說了,大家都知道。軟引用一般可以用來做緩存,比如一個很大的對象,我們重新加載比較耗時間,用強引用又可能內存溢出,就用軟引用咯。

弱引用的典型引用就是WeakHashMap,有時候我們想要JVM快速回收某個對象時,就用弱引用。

下面來個例子:

package weakmap;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;

public class ThreadGC implements Runnable {

	private WeakReference<byte[]> k;
	private ReferenceQueue referenceQueue;
	public void setReferenceQueue(ReferenceQueue referenceQueue) {
		this.referenceQueue=referenceQueue;
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		int cnt = 0;
		try {
			while((k = (WeakReference) referenceQueue.remove()) != null) {
			    System.out.println((cnt++) + "回收了:" + k);
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
package weakmap;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;

public class Client {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Object value = new Object();
		Map<Object, Object> map = new HashMap<>();
		ReferenceQueue referenceQueue=new ReferenceQueue<>();
		ThreadGC threadGC=new ThreadGC();
		threadGC.setReferenceQueue(referenceQueue);
		
		new Thread(threadGC).start();
		
		for(int i = 0;i < 10000;i++) {
		    byte[] bytes = new byte[1024*1024];
		    WeakReference<byte[]> weakReference = new WeakReference<byte[]>(bytes, referenceQueue);
		    map.put(weakReference, value);
		}
		System.out.println("map.size->" + map.size());
	}

}
WeakHashMap應該也是類似的實現,把HashMap的key用弱引用,可以實現快速內存回收。

虛引用

下面來個例子:

package weakmap;

import java.lang.ref.PhantomReference;  
import java.lang.ref.Reference;  
import java.lang.ref.ReferenceQueue;  
import java.lang.reflect.Field;  
  
public class Test {  
    public static boolean isRun = true;  
  
    @SuppressWarnings("static-access")  
    public static void main(String[] args) throws Exception {  
        String abc = new String("abc");  
        System.out.println(abc.getClass() + "@" + abc.hashCode());  
        final ReferenceQueue<String> referenceQueue = new ReferenceQueue<String>();  
        
        new Thread() {  
            public void run() {  
                while (isRun) {  
                    Object obj = referenceQueue.poll();  //引用隊列裏有對象
                    if (obj != null) {  
                        try {  
                            Field rereferent = Reference.class  
                                    .getDeclaredField("referent");  
                            rereferent.setAccessible(true);  
                            Object result = rereferent.get(obj);  
                            System.out.println("gc will collect:"  
                                    + result.getClass() + "@"  
                                    + result.hashCode() + "\t"  
                                    + (String) result);  
                        } catch (Exception e) {  
                            e.printStackTrace();  
                        }  
                    }  
                }  
            }  
        }.start();  
        
        PhantomReference<String> abcWeakRef = new PhantomReference<String>(abc,  
                referenceQueue);  
        abc = null;  
        Thread.currentThread().sleep(3000);  
        System.gc();  
        Thread.currentThread().sleep(3000);  
        isRun = false;  
    }  
}  



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章