https://github.com/Androooid/treasure/blob/master/source/lightsky/posts/mat_usage.mdjava
JAVA虚拟机经过可达性(Reachability)来判断对象是否存活,基本思想:以"GC Roots"的对象做为起始点向下搜索,搜索造成的路径称为引用链,当一个对象到GC Roots没有任何引用链相连(即不可达的),则该对象被断定为能够被回收的对象,反之不能被回收。git
GC Roots能够是如下任意对象github
对象无用了,但仍然可达(未释放),垃圾回收器没法回收。web
普通的java引用,咱们一般new的对象就是: StringBuffer buffer = new StringBuffer();
若是一个对象经过一串强引用链可达,那么它就不会被垃圾回收。你确定不但愿本身正在使用的引用被垃圾回收器回收吧。但对于集合中的对象,应在不使用的时候移除掉,不然会占用更多的内存,致使内存泄漏。缓存
当对象是Soft reference可达时,gc会向系统申请更多内存,而不是直接回收它,当内存不足的时候才回收它。所以Soft reference适合用于构建一些缓存系统,好比图片缓存。函数
WeakReference不会强制对象保存在内存中。它拥有比较短暂的生命周期,容许你使用垃圾回收器的能力去权衡一个对象的可达性。在垃圾回收器扫描它所管辖的内存区域过程当中,一旦gc发现对象是weakReference可达,就会把它放到ReferenceQueue中,等下次gc时回收它。 WeakReference<Widget> weakWidget = new WeakReference<Widget>(widget);
系统为咱们提供了WeakHashMap,和HashMap相似,只是其key使用了weak reference。若是WeakHashMap的某个key被垃圾回收器回收,那么entity也会自动被remove。post
因为WeakReference被GC回收的可能性较大,所以,在使用它以前,你须要经过weakObj.get()去判断目的对象引用是否已经被回收..net
一旦WeakReference.get()返回null,它指向的对象就会被垃圾回收,那么WeakReference对象就没有用了,意味着你应该进行一些清理。好比在WeakHashMap中要把回收过的key从Map中删除掉,避免无用的的weakReference不断增加。 ReferenceQueue可让你很容易地跟踪dead references。WeakReference类的构造函数有一个ReferenceQueue参数,当指向的对象被垃圾回收时,会把WeakReference对象放到ReferenceQueue中。这样,遍历ReferenceQueue能够获得全部回收过的WeakReference。线程
和soft,weak Reference区别较大,它的get()方法老是返回null。这意味着你只能用PhantomReference自己,而得不到它指向的对象。当WeakReference指向的对象变得弱可达(weakly reachable)时会当即被放到ReferenceQueue中,这在finalization、garbage collection以前发生。理论上,你能够在finalize()方法中使对象“复活”(使一个强引用指向它就好了,gc不会回收它)。但无法复活PhantomReference指向的对象。而PhantomReference是在garbage collection以后被放到ReferenceQueue中的,无法复活。code
关于Phantom reference的更多讨论,请参考:understanding-weak-references