1、强引用(StrongReference)
强引用不会被GC回收,并且在java.lang.ref里也没有实际的对应类型。举个例子来说:
Object obj = new Object();
这里的obj引用便是一个强引用,不会被GC回收。
2、软引用(SoftReference)
软引用在JVM报告内存不足的时候才会被GC回收,否则不会回收,正是由于这种特性软引用在caching和pooling中用处广泛。软引用的用法:
Object obj = new Object();
SoftReference<Object> softRef = new SoftReference(obj);
// 使用 softRef.get() 获取软引用所引用的对象
Object objg = softRef.get();
3、弱引用(WeakReference)
当GC一但发现了弱引用对象,将会释放WeakReference所引用的对象。弱引用使用方法与软引用类似,但回收策略不同。
4、虚引用(PhantomReference)
当GC一但发现了虚引用对象,将会将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报告内存不足的时候才会被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// 清除强引用,触发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());}//当GC一但发现了弱引用对象,将会释放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,当GC发现了虚引用,GC会将phanRef插入进我们之前创建时传入的refQueue队列// 注意,此时phanRef所引用的obj对象,并没有被GC回收,在我们显式地调用refQueue.poll返回phanRef之后// 当GC第二次发现虚引用,而此时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);/// 调用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) );}}
现在如果GC想要回收registeredObjects中的object,便能够实现了,同样在使用HashMap如果想实现如上的效果,一种更好的实现是使用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.
翻译一下:
虚引用在实现一个对象被回收之前必须做清理操作是很有用的。有时候,他们比finalize()方法更灵活。
很明显的,虚引用可以用来做对象被回收之前的清理工作
参考:http://www.cnblogs.com/newcj/archive/2011/05/15/2046882.html