了解Java的参考类:SoftReference,WeakReference和PhantomReference


81

有人可以解释这三个Reference类之间的区别吗(或发布一个很好的解释的链接)?SoftReference> WeakReference> PhantomReference,但当我会用每一个?为什么会有一个,WeakHashMap但没有SoftHashMapPhantomHashMap

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

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在每个语句之前检查是否为null(这是错误的,但是我应该怎么办)?很抱歉急速提问,但我无法理解这些Reference课程...谢谢!


1
为什么有一个WeakHashMap但没有SoftHashMapPhantomHashMap很好的问题,为什么我以前没有注意到这个问题?
Mehraj Malik

1
这项ref != null检查没有任何意义。ref永远不会null
霍尔格

加上问:strongRef --> weakRef --> objA。现在,是否objA将被GC,因为它具有来自的间接引用strongRef
samshers

Answers:


60

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

SoftReference当希望引用的对象保持活动状态,直到主机进程的内存不足时,可以使用a 。在收集器需要释放内存之前,该对象将无法进行收集。松散地说,绑定了一种SoftReference方法,“将对象固定到无法使用为止”。

相反,WeakReference当您不想影响参考对象的寿命时,请使用a ;否则,请使用。您只想被引用的对象进行单独的断言,只要它仍然有效即可。绑定对象的存在不影响对象的收集资格WeakReference。从WeakReferences对象实例到相关属性的外部映射(只要相关对象还活着就只需记录该属性)之类的东西,对于s和是很好的用法WeakHashMap

最后一个PhantomReference-很难描述。像一样WeakReference,这样的界限PhantomReference对引用对象的生存期没有影响。但是与其他引用类型不同,您甚至不能取消引用a PhantomReference。从某种意义上说,它并不是指向呼叫者可以告诉的内容。它仅允许人们将一些相关数据与所引用的对象相关联,这些数据以后可以PhantomReference在相关对象中排队时进行检查并采取行动ReferenceQueue。通常,一个类型是从该类型派生的,PhantomReference并在该派生类型中包含一些其他数据。不幸的是,要使用这种派生类型涉及一些向下转换。

在示例代码中,ref不能为null的引用(或者,如果您更喜欢“变量”)。而是通过调用获得的值Reference#get()可能为null。如果发现它为空,则为时已晚。引用的对象已经在收集中:

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

加上问:strongRef --> weakRef --> objA。现在,是否objA将被GC,因为它具有来自的间接引用strongRef
samshers

如果我正确理解您的问题,@ samshersobjA可作为垃圾回收。固定aWeakReferenceWeakReference指向的对象没有影响。
seh

在链上没有很强的参考意义。因为objA要进行垃圾收集,必须首先删除弱引用。强烈推荐指向弱引用,使弱引用不适合进行GC
samshers

不,WeakReference不需要收集objA即可收集。在WeakReference不保留objA活着。相反,它是一种查找objA活着的时间(不影响其寿命)并检测收集器何时将其取走的方法。
seh

6

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

PhantomHashMapget总是返回null幻像引用,效果不佳。

缓存很困难,因此SoftHashMap可能无法如您所想的那样工作。但是,我相信Google的馆藏库包含一般的参考地图实现。

您应始终检查是否get返回non- null。(请注意,不要检查Reference引用本身是否不是- null。)对于内嵌字符串,它总是会,但是(一如既往)不要试图对其进行“巧妙处理”。


链接已过期。
Mehraj Malik

@MehrajMalik链接已修复。
Tom Hawtin-大头钉'17

加上问:strongRef --> weakRef --> objA。现在,是否objA将被GC,因为它具有来自的间接引用strongRef
samshers


0
String str = new String("hello, world");
WeakReference<String> ref = new WeakReference<String>(str);
str = null;

if (ref != null) {                 
    System.gc(); 
    System.out.println(ref.get());
}

在这种情况下,它将输出null。System.gc()此处的呼叫很重要。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.