Java中的四大引用(强引用,弱引用,软引用,虚引用)

引用这个概念经常被提及,今天总结一下。

强引用

强引用即(StrongReference)我们最常使用的引用,A a=new A()。这个a就是一个强引用。


软引用

即(SoftReference),


Object obj = new Object();
SoftReference sf = new SoftReference(obj);
obj = null;
sf.get();//有时候会返回null 
  

弱引用

即(WeakReference

Object obj = new Object();
WeakReference wf = new WeakReference(obj);
obj = null;
wf.get();//有时候会返回null
wf.isEnQueued();//返回是否被垃圾回收器标记为即将回收的垃圾 
  

虚引用

即(PhantomReference

Java中的四大引用(强引用,弱引用,软引用,虚引用)_第1张图片

Object obj = new Object();
PhantomReference pf = new PhantomReference(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 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 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 weakReference = new WeakReference(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 referenceQueue = new ReferenceQueue();  
        
        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 abcWeakRef = new PhantomReference(abc,  
                referenceQueue);  
        abc = null;  
        Thread.currentThread().sleep(3000);  
        System.gc();  
        Thread.currentThread().sleep(3000);  
        isRun = false;  
    }  
}  



你可能感兴趣的:(Java)