原
Java强引用、软引用、弱引用、虚引用详解
2015年04月25日 16:20:40
阅读数:5762
原创作品,出自 “晓风残月xj” 博客,欢迎转载,转载时请务必注明出处(http://blog.csdn.net/xiaofengcanyuexj)。
由于各种原因,可能存在诸多不足,欢迎斧正!
Java中没有指针的概念,而引用就是一个弱化的指针,保证开发不能任意操作内存。最近整理了一下之前不明白的各种级别引用:强引用、软引用、弱引用、虚引用,它们的特点和应用场景汇总如下:
1、强引用
如果一个对象具有强引用,GC绝不会回收它;当内存空间不足,JVM宁愿抛出OutOfMemoryError错误。一般new出来的对象都是强引用,如下
-
//强引用
-
User strangeReference=new User();
2、软引用
如果一个对象具有软引用,当内存空间不足,GC会回收这些对象的内存,使用软引用构建敏感数据的缓存。
在JVM中,软引用是如下定义的,可以通过一个时间戳来回收,下面引自JVM:
-
public class SoftReference<T> extends Reference<T> {
-
/**
-
* Timestamp clock, updated by the garbage collector
-
*/
-
static private long clock;
-
/**
-
* Timestamp updated by each invocation of the get method. The VM may use
-
* this field when selecting soft references to be cleared, but it is not
-
* required to do so.
-
*/
-
private long timestamp;
-
/**
-
* Creates a new soft reference that refers to the given object. The new
-
* reference is not registered with any queue.
-
*
-
* @param referent object the new soft reference will refer to
-
*/
-
public SoftReference(T referent) {
-
super(referent);
-
this.timestamp = clock;
-
}
-
/**
-
* Creates a new soft reference that refers to the given object and is
-
* registered with the given queue.
-
*
-
* @param referent object the new soft reference will refer to
-
* @param q the queue with which the reference is to be registered,
-
* or <tt>null</tt> if registration is not required
-
*
-
*/
-
public SoftReference(T referent, ReferenceQueue<? super T> q) {
-
super(referent, q);
-
this.timestamp = clock;
-
}
-
/**
-
* Returns this reference object's referent. If this reference object has
-
* been cleared, either by the program or by the garbage collector, then
-
* this method returns <code>null</code>.
-
*
-
* @return The object to which this reference refers, or
-
* <code>null</code> if this reference object has been cleared
-
*/
-
public T get() {
-
T o = super.get();
-
if (o != null && this.timestamp != clock)
-
this.timestamp = clock;
-
return o;
-
}
-
}
软引用的声明的借助强引用或者匿名对象,使用泛型SoftReference<T>;可以通过get方法获得强引用。具体如下:
-
//软引用
-
SoftReference<User>softReference=new SoftReference<User>(new User());
-
strangeReference=softReference.get();//通过get方法获得强引用
3、弱引用
如果一个对象具有弱引用,在GC线程扫描内存区域的过程中,不管当前内存空间足够与否,都会回收内存,利用jdk中的ThreadLocal就是弱引用的,具体间下面的详细说明。
在JVM中,弱引用是如下定义的,下面引自JVM:
-
public class WeakReference<T> extends Reference<T> {
-
/**
-
* Creates a new weak reference that refers to the given object. The new
-
* reference is not registered with any queue.
-
*
-
* @param referent object the new weak reference will refer to
-
*/
-
public WeakReference(T referent) {
-
super(referent);
-
}
-
/**
-
* Creates a new weak reference that refers to the given object and is
-
* registered with the given queue.
-
*
-
* @param referent object the new weak reference will refer to
-
* @param q the queue with which the reference is to be registered,
-
* or <tt>null</tt> if registration is not required
-
*/
-
public WeakReference(T referent, ReferenceQueue<? super T> q) {
-
super(referent, q);
-
}
-
}
弱引用的声明的借助强引用或者匿名对象,使用泛型WeakReference<T>,具体如下:
-
//弱引用
-
WeakReference<User>weakReference=new WeakReference<User>(new User());
4、虚引用
如果一个对象仅持有虚引用,在任何时候都可能被垃圾回收,虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列联合使用,虚引用主要用来跟踪对象 被垃圾回收的活动。
在JVM中,虚引用是如下定义的,下面引自JVM:
-
//虚引用
-
PhantomReference<User> phantomReference=new PhantomReference<User>(new User(),new ReferenceQueue<User>());