了解Java的引用类:SoftReference、WeakReference和PhantomReference
了解Java的引用类:SoftReference、WeakReference和PhantomReference
有人能解释一下三个引用类之间的区别吗(或者提供一个链接来解释)?SoftReference
> WeakReference
> PhantomReference
,但是我应该在什么时候使用它们呢?为什么有 WeakHashMap
,但没有 SoftHashMap
或者 PhantomHashMap
?
如果我使用以下代码...
WeakReference ref = new WeakReference("Hello!"); if (ref != null) { // ref can get collected at any time... System.gc(); // Let's assume ref gets collected here. System.out.println(ref.get()); // Now what?! }
...会发生什么?我是否需要在每个语句之前检查 ref
是否为空(这是错误的,但我应该怎么办)?抱歉问题有点多,但我很难理解这些 Reference
类... 谢谢!
一个链接:https://community.oracle.com/blogs/enicholas/2006/05/04/understanding-weak-references
PhantomHashMap
不会很好的工作,因为幽灵引用对应的 get
总是返回 null
。
缓存很棘手,因此 SoftHashMap
可能不如你想象的那样好。但是,我相信谷歌的集合库包含了一个通用的引用映射实现。
你应该始终检查 get
是否返回非 null
。(注意,不要检查 Reference
引用本身是否为非 null
。)在字符串内部化的情况下,它总是会的,但(如往常一样)不要试图“聪明地”处理它。
Java库文档中的java.lang.ref
包的文档描述了三种显式引用类型的弱化强度。
当您希望引用的对象在主机进程的内存不足时仍然保持活动状态时,可以使用SoftReference
。该对象直到收集器需要释放内存之前才能被回收。粗略地说,绑定SoftReference
的含义是“把对象固定住,直到不能再固定为止”。
相反,当您不希望影响引用对象的生命周期时,可以使用WeakReference
。您仅希望对引用对象做出单独的断言,只要引用对象存活即可。存在绑定的WeakReference
不会影响对象被收集的资格。例如将对象实例映射到相关属性的外部映射,只要相关对象存活,就需要记录属性,这是使用WeakReference
和WeakHashMap
的好方法。
最后一个-PhantomReference
-更难以描述。像WeakReference
一样,这样绑定的PhantomReference
对引用对象的生命周期没有影响。但是,与其他引用类型不同,甚至连PhantomReference
都无法取消引用。在某种意义上,它并没有指向它指向的东西,就像调用者所看到的那样。它只允许将某些相关数据与引用对象关联起来,当PhantomReference
排队在其相关的ReferenceQueue
中时,可以检查和操作这些数据。通常,从PhantomReference
派生出一个类型,并在该派生类型中包含一些附加数据。不幸的是,要使用这样的派生类型需要一些向下转换。
在您的示例代码中,可以为ref
引用(或者,如果您愿意,是“变量”)为空。相反,调用Reference#get()
时获取的值可能为空。如果发现其为空,则为时已晚,引用对象已开始进入被回收的过程:
final String val = ref.get(); if (null != val) { // "val" is now pinned strongly. } else { // "val" is already ready to be collected. }