Java强软弱虚引用Referencehtml
学习过程记录,加深理解,提高文字组合表达能力。也但愿能给学习Reference的同窗一些灵感java
源码基于jdk1.8.0_111:api
由代码量上也能够初步判断,Java引用,并不太复杂缓存
Package java.lang.ref:网络
提供引用对象类,它支持与垃圾收集器进行有限程度的交互。oracle
Provides reference-object classes, which support a limited degree of interaction with the garbage collector. --oracle.comless
java.lang.ref包中提供了几个类:SoftReference类、WeakReference类和PhantomReference类,它们分别表明软引用、弱引用和虚引用。ReferenceQueue类表示引用队列,它能够和这三种引用类联合使用,以便跟踪Java虚拟机回收所引用的对象的活动。ide
SoftReference:软引用–>当虚拟机内存不足时,将会回收它指向的对象;须要获取对象时,能够调用get方法。函数
能够经过java.lang.ref.SoftReference使用软引用。一个持有软引用的对象,不会被JVM很快回收,JVM会根据当前堆的使用状况来判断什么时候回收。当堆的使用率临近阈值时,才会回收软引用的对象。学习
例如从网络上获取图片,而后将获取的图片显示的同时,经过软引用缓存起来。当下次再去网络上获取图片时,首先会检查要获取的图片缓存中是否存在,若存在,直接取出来,不须要再去网络上获取。
在垃圾回收器对这个Java对象回收前,SoftReference类所提供的get方法会返回Java对象的强引用,一旦垃圾线程回收该Java对象以后,get方法将返回null。因此在获取软引用对象的代码中,必定要判断是否为null,以避免出现NullPointerException异常致使应用崩溃。
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; } }
若是一个对象只具备弱引用,那么在垃圾回收器线程扫描的过程当中,一旦发现了只具备弱引用的对象,无论当前内存空间足够与否,都会回收它的内存。不过,因为垃圾回收器是一个优先级很低的线程,所以不必定会很快发现那些只具备弱引用的对象。
弱引用也能够和一个引用队列(ReferenceQueue)联合使用,若是弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。
同软引用SoftReference
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); } }
没有其余代码,GC时被回收掉。
虚引用是全部引用类型中最弱的一个。一个持有虚引用的对象,和没有引用几乎是同样的,随时均可能被垃圾回收器回收。当试图经过虚引用的get()方法取得强引用时,老是会失败。而且,虚引用必须和引用队列一块儿使用,它的做用在于跟踪垃圾回收过程。 当垃圾回收器准备回收一个对象时,若是发现它还有虚引用,就会在垃圾回收后,销毁这个对象,奖这个虚引用加入引用队列。
未遇到
public class PhantomReference<T> extends Reference<T> { /** * Returns this reference object's referent. Because the referent of a * phantom reference is always inaccessible, this method always returns * <code>null</code>. * * @return <code>null</code> */ public T get() { return null; } /** * Creates a new phantom reference that refers to the given object and * is registered with the given queue. * * <p> It is possible to create a phantom reference with a <tt>null</tt> * queue, but such a reference is completely useless: Its <tt>get</tt> * method will always return null and, since it does not have a queue, it * will never be enqueued. * * @param referent the object the new phantom 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 PhantomReference(T referent, ReferenceQueue<? super T> q) { super(referent, q); } }
实现了链表结构的队列
当系统要回收Reference持有的对象引用referent的时候,Reference的enqueue函数会被调用,而在这个函数中调用了ReferenceQueue的enqueue函数。
Reference与引用队列(ReferenceQueue)联合使用,若是弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。
对本文有什么建议(内容、写做风格等),欢迎留言提出,感谢!