了解 Java 的参考类:软引用、弱引用和幻影引用

有人可以解释三个参考类之间的区别(或者发布一个很好的解释的链接)吗? > >,但我什么时候会使用每个?为什么有一个 但是 没有 或 ?SoftReferenceWeakReferencePhantomReferenceWeakHashMapSoftHashMapPhantomHashMap

如果我使用以下代码...

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?!
}

...会发生什么情况?我是否必须在每个语句之前检查是否为 null(这是错误的,但我该怎么办)?很抱歉快速的问题,但我很难理解这些课程......谢谢!refReference


答案 1

java.lang.ref 包的 Java 库文档描述了三种显式引用类型的强度下降。

当您希望引用的对象保持活动状态直到主机进程内存不足时,可以使用 。在收集器需要释放内存之前,该对象将不符合收集条件。松散地说,绑定意味着“固定对象,直到你不能再了。SoftReferenceSoftReference

相比之下,当您不想影响被引用对象的生存期时,请使用;您只想引用的对象进行单独的断言,只要它仍然处于活动状态即可。对象的收集资格不受绑定 s 的存在的影响。类似于从对象实例到相关属性的外部映射,只要相关对象处于活动状态,就需要记录属性,这对于 s 和 .WeakReferenceWeakReferenceWeakReferenceWeakHashMap

最后一个——更难描述。就像 ,这样的绑定对被引用对象的生存期没有影响。但与其他引用类型不同,人们甚至不能取消引用 。从某种意义上说,就呼叫者所知,它并不指向它所指向的东西。它只允许将一些相关数据与引用的对象相关联 - 这些数据可以在以后在其相关对象中排队时进行检查和操作。通常,从该派生类型派生类型,并在该派生类型中包含一些其他数据。不幸的是,使用这种派生类型涉及一些下沉。PhantomReferenceWeakReferencePhantomReferencePhantomReferencePhantomReferenceReferenceQueuePhantomReference

在示例代码中,引用(或者,如果您愿意,还可以使用“变量”)为 null。相反,通过调用 Reference#get() 获得的值可能为 null。如果发现它为空,则为时已晚;引用的对象已经在收集过程中:ref

final String val = ref.get();
if (null != val)
{
  // "val" is now pinned strongly.
}
else
{
  // "val" is already ready to be collected.
}

答案 2

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

PhantomHashMap不会很好地工作,因为总是返回幻像引用。getnull

缓存很困难,因此可能不如您想象的那么好。但是,我相信Google的集合库包含了一个通用的参考地图实现。SoftHashMap

您应始终检查是否返回非。(请注意,不检查引用本身是否不是-。在实习字符串的情况下,它总是会,但(一如既往)不要试图“聪明”它。getnullReferencenull