理解弱引用

Soft,Weak,Phantom Reference

java.lang.ref.Reference<T> 是他们共同的父类, 提供通过 Reference.get()间接引用T对象的功能.  而Reference内部对T的引用(T referent),不同于一般引用,GC会对其特殊处理: 一般来说 当一个对象的所有引用都是Reference引用时, GC会回收它, 但具体回收的策略和时间, GC会根据具体的实现类区分: 

WeakReference:当GC检测到所有引用都是WeakReference时会依次做: 1,原子的删除所有此Reference的引用及级联reference, 之后get()返回null. 2.标识这些对象为finalizable.  3. ReferenceQueue.enqueue.    主要的应用是 WeakHashMap将 Entry继承WeakReference, 并将key赋予WeakReference.referent.  由其他调用(put(),size()等)触发清除: poll ReferenceQueue中的Entry将其移除.

SoftReference: 和Weak的区别在于, 只有当内存满的情况下才会尝试回收.  

PhantomReference: Phantom和Weak和Soft不同, 首先,PhantomReference get()永远返回 null。另外,调用enqueue的时机不同,Weak是在finalize()和GC前, Phantom是在真正内存擦除后。这样会更安全的做一些善后清理(post-mortem)工作,比如 DirectByteBuffer的内存释放.

考虑一种情况,如果Object重写了finalize(), 这个对象有可能被复活,比如给一个Strong ref, 所以重写finalize的object需要至少2个GC周期来彻底回收。此时WeakReference会在第一个GC之前enqueue,而如果是PhantomReference则会在彻底回收之后才enqueue.

所以当PhantomReference被enqueue到ReferenceQueue时,就说明object确实被彻底回收了(reclaimed), 利用这一点,可以放心的做一些cleanup的工作,而不用担心finalize()复活对象。这可以看做是 一种更灵活的替代Java finalize()的机制。   典型的应用就是 DirectByteBuffer, 因为不存在被复活的风险,所以堆外内存的释放是通过PhantomReference实现的.




https://community.oracle.com/blogs/enicholas/2006/05/04/understanding-weak-references

https://en.wikipedia.org/wiki/Phantom_reference

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • java引用体系中我们最熟悉的就是强引用类型,如 A a= new A();这是我们经常说的强引用StrongRe...
    tracy_668阅读 897评论 0 11
  • Java中一共有4种引用类型(其实还有一些其他的引用类型比如FinalReference):强引用、软引用、弱引用...
    往之farmer阅读 665评论 4 4
  • Java中一共有4种引用类型(其实还有一些其他的引用类型比如FinalReference):强引用、软引用、弱引用...
    taj3991阅读 331评论 0 0
  • java引用疑问 java 引用:深入分析Object.finalize方法的实现原理 - 简书Java软引用究竟...
    lesline阅读 349评论 0 0
  • 引用的分类 Java 1.2以后,除了普通的引用外,Java还定义了软引用、弱引用、虚引用等概念。 强引用:GC ...
    刘惜有阅读 885评论 0 1