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

来源:互联网 发布:免费cad制作软件 编辑:程序博客网 时间:2024/05/16 07:22

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

强引用

强引用即(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();//有时候会返回nullwf.isEnQueued();//返回是否被垃圾回收器标记为即将回收的垃圾

虚引用

即(PhantomReference

Object obj = new Object();PhantomReference<Object> pf = new PhantomReference<Object>(obj);obj=null;pf.get();//永远返回nullpf.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;}@Overridepublic void run() {// TODO Auto-generated method stubint cnt = 0;try {while((k = (WeakReference) referenceQueue.remove()) != null) {    System.out.println((cnt++) + "回收了:" + k);}} catch (InterruptedException e) {// TODO Auto-generated catch blocke.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 stubObject 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;      }  }  



1 0