问题描述
有人可以解释三个参考类之间的区别吗(或发布一个很好解释的链接)?SoftReference
> WeakReference
> PhantomReference
,但是我什么时候使用每一个?为什么有 WeakHashMap
而没有 SoftHashMap
或 PhantomHashMap
?
Can someone explain the difference between the three Reference classes (or post a link to a nice explanation)? SoftReference
> WeakReference
> PhantomReference
, but when would I use each one? Why is there a WeakHashMap
but no SoftHashMap
or PhantomHashMap
?
如果我使用以下代码...
And if I use the following code...
WeakReference<String> ref = new WeakReference<String>("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
类...谢谢!
...what happens? Do I have to check if ref
is null before every statement (this is wrong, but what should I do)? Sorry for the rapid-fire questions, but I'm having trouble understanding these Reference
classes... Thanks!
推荐答案
Java 库 java.lang.ref
包 的文档描述了三种显式引用类型的强度递减.
The Java library documentation for the java.lang.ref
package characterizes the decreasing strength of the three explicit reference types.
当您希望引用的对象保持活动状态直到主机进程内存不足时,您可以使用 SoftReference
.在收集器需要释放内存之前,对象将不符合收集条件.笼统地说,绑定一个 SoftReference
意味着固定对象,直到你不能再固定为止."
You use a SoftReference
when you want the referenced object to stay alive until the host process is running low on memory. The object will not be eligible for collection until the collector needs to free memory. Loosely stated, binding a SoftReference
means, "Pin the object until you can't anymore."
相比之下,当您不想影响引用对象的生命周期时,请使用 WeakReference
;你只是想对被引用的对象做一个单独的断言,只要它保持活动.对象的收集资格不受绑定 WeakReference
的影响.类似于从对象实例到相关属性的外部映射,只要相关对象还活着,就需要记录该属性,这对于 WeakReference
s 和 WeakHashMap
.
By contrast, use a WeakReference
when you don't want to influence the referenced object's lifetime; you merely want to make a separate assertion about the referenced object, so long as it remains alive. The object's eligibility for collection is not influenced by the presence of bound WeakReference
s. Something like an external mapping from object instance to related property, where the property need only be recorded so long as the related object is alive, is a good use for WeakReference
s and WeakHashMap
.
最后一个——PhantomReference
——更难描述.与WeakReference
一样,这样的绑定PhantomReference
不会影响被引用对象的生命周期.但与其他引用类型不同的是,人们甚至不能取消引用 PhantomReference
.从某种意义上说,它并不指向它所指向的东西,就调用者所知.它只允许将一些相关数据与引用对象相关联——当 PhantomReference
在其相关的 ReferenceQueue
中排队时,这些数据可以稍后被检查和操作.通常从 PhantomReference
派生一个类型,并在该派生类型中包含一些额外的数据.不幸的是,使用这种派生类型需要进行一些向下转换.
The last one—PhantomReference
—is harder to characterize. Like WeakReference
, such a bound PhantomReference
exerts no influence on the referenced object's lifetime. But unlike the other reference types, one can't even dereference a PhantomReference
. In a sense, it doesn't point to the thing it points to, as far as callers can tell. It merely allows one to associate some related data with the referenced object—data that can later be inspected and acted upon when the PhantomReference
gets queued in its related ReferenceQueue
. Normally one derives a type from PhantomReference
and includes some additional data in that derived type. Unfortunately, there's some downcasting involved to make use of such a derived type.
在您的示例代码中,不是 ref
引用(或者,如果您愿意,可以是变量")可以为空.相反,它是通过调用 Reference#get()
可能为空.如果发现它为空,则为时已晚;引用的对象已经在被收集的路上:
In your example code, it's not the ref
reference (or, if you prefer, "variable") that can be null. Rather, it's the value obtained by calling Reference#get()
that may be null. If it is found to be null, you're too late; the referenced object is already on its way to being collected:
final String val = ref.get();
if (null != val)
{
// "val" is now pinned strongly.
}
else
{
// "val" is already ready to be collected.
}
这篇关于了解 Java 的引用类:SoftReference、WeakReference 和 PhantomReference的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!