java基础-Reference一
下面对SoftReference、WeakReference、PhantomReference三个Reference做相同的测试。
可以看到三个Reference表现各不相同,
SoftReference在gc前持有referent,在gc后也没有改变,因为SoftReference中的referent只有在java heap紧张时才会被回收(无法保证是在full gc时回收,只能保证在OOM前回收),而此时java heap显然很宽裕。
WeakReference在gc前同样持有referent,但在gc后referent就被回收了,这是因为与SoftReference不同,WeakReference不论java heap是否紧张,遇到gc就会回收。referent被回收后,WeakReference会被放入其所注册的队列中,但此时已无法取得referent了,除非再次创建(比如扩展WeakReference,加入业务id成员变量,通过id再次获取业务对象,从而创建对应的referent)。
PhantomReference始终都无法获取到referent(但是在PhantomReference中确认存有referent,对于这三种Reference来说referent的共同作用是让gc通过Reference找到referent,然后决定是否回收,对于SoftReference和WeakReference来说还可以通过api得到referent,而PhantomReference的获取referent的api始终返回null),也就是说PhantomReference不适合用来存取referent,是能用来跟踪referent是否被gc,这也是PhantomReference只提供有ReferenceQueue构造器的原因,如果无ReferenceQueue,那PhantomReference可谓是一点儿用都没有了(sun.misc.Cleaner例外,因为Cleaner在Reference内部被特殊处理了)。