#### Java四种引用包括强引用,软引用,弱引用,虚引用
1. 强引用
只要引用存在,垃圾回收器永远不会回收
Object obj = new Object(); //可直接通过obj取得对应的对象 如obj.equels(new Object());
而这样 obj对象对后面new Object的一个强引用,只有当obj这个引用被释放之后,对象才会被释放掉,这也是我们经常所用到的编码形式。
2. 软引用
非必须引用,内存溢出之前进行回收,可以通过以下代码实现
Object obj = new Object();
SoftReference
obj = null;
sf.get(); //有时候会返回null
这时候sf是对obj的一个软引用,通过sf.get()方法可以取到这个对象,当然,当这个对象被标记为需要回收的对象时,则返回null;
软引用主要用户实现类似缓存的功能,在内存足够的情况下直接通过软引用取值,无需从繁忙的真实来源查询数据,提升速度;当内存不足时,自动删除这部分缓存数据,从真正的来源查询这些数据。
3. 弱引用
第二次垃圾回收时回收,可以通过如下代码实现、
Object obj = new Object();
WeakReference
obj = null;
wf.get();//有时候会返回null
弱引用是在第二次垃圾回收时回收,短时间内通过弱引用取对应的数据,可以取到,当执行过第二次垃圾回收时,将返回null。
弱引用主要用于监控对象是否已经被垃圾回收器标记为即将回收的垃圾,可以通过弱引用的isEnQueued方法返回对象是否被垃圾回收器标记。
WeakReference(T referent, ReferenceQueue super T> q):与上面的构造方法比较,多了个ReferenceQueue,在对象被回收后,会把弱引用对象,也就是WeakReference对象或者其子类的对象,放入队列ReferenceQueue中,注意**不是被弱引用的对象**,被弱引用的对象已经被回收了。
```
Object obj = new Object();
ReferenceQueue queue = new ReferenceQueue();
WeakReference
boolean enqueued = wrf.isEnqueued();
System.out.println("回收之前 WeakReference:"+wrf);
System.out.println("回收之前 Object:"+wrf.get());
obj = null;
System.gc();
System.runFinalization(); //让gc立刻执行
Reference poll = null;
while(( poll = queue.poll() ) != null){
System.out.println("ReferenceQueue 中"+poll);
}
boolean enqueued1 = wrf.isEnqueued();
System.out.println("回收之后 Object:"+wrf.get());
```
```
回收之前 WeakReference:java.lang.ref.WeakReference@6f94fa3e
回收之前 Object:java.lang.Object@5e481248
ReferenceQueue 中java.lang.ref.WeakReference@6f94fa3e
回收之后 Object:null
```
```
String key = new String("abc");
String value = new String("value");
WeakHashMap
weakHashMap.put(key,value);
System.out.println("gc before weakHashMap size:"+weakHashMap.size() );
key = null;
System.gc();
System.runFinalization();
System.out.println("gc after weakHashMap size:"+weakHashMap.size() );
```
```
gc before weakHashMap size:1
gc after weakHashMap size:0
```
4. 虚引用
垃圾回收时回收,无法通过引用取到对象值,可以通过如下代码实现
Object obj = new Object();
PhantomReference
obj=null;
pf.get();//永远返回null
虚引用是每次垃圾回收的时候都会被回收,通过虚引用的get方法永远获取到的数据为null,因此也被成为幽灵引用。
虚引用主要用于检测对象是否已经从内存中删除。
```
Object obj1 = new Object();
System.out.println(obj1);
ReferenceQueue
PhantomReference
System.out.println(phantom);
System.out.println(refQueue.poll());
obj1 = null;
System.gc();
System.runFinalization();
System.out.println(phantom.get()); // 由于这个返回永远是null
Reference ref = null;
while((ref = refQueue.poll()) != null){
Field rereferent = Reference.class
.getDeclaredField("referent");
rereferent.setAccessible(true);
Object result = rereferent.get(ref);
System.out.println("gc will collect:"
+ result.getClass() + "@"
+ result.hashCode() + "\t"
+ result);
}
```
##### 立刻手动执行GC回收,
```
System.gc();
System.runFinalization();
```