ReferenceQueue的java含义
我试图理解类ReferenceQueue
它是的可选构造函数参数
SoftReference
及
WeakReference
它也是PhantomReference
的强制参数
根据我读到的信息,我可以写一些论文
a)对于PhantomReference方法,get始终返回null
(b)
对于幻影参考:
1.gc检测到可以从内存中删除对象
2.对放入引用队列的对象的引用
当我们从队列调用clear或link-to-reference时,因为无法访问而gc看到
3.finalize方法调用
4.可用内存
对于弱/软引用:
1.gc检测到可以从内存中删除对象
2.finalize方法调用
3.可用内存
4.对放入队列的对象的引用
- 什么时候可以将第二个参数传递给
XXXReference
构造函数李> - 我能得到什么帮助李>
- 为什么
PhantomReference
没有ReferenceQueue
的构造函数李> - 有ReferenceQuee的get方法总是返回null的原因是什么李>
# 1 楼答案
你想什么时候做就什么时候做。当引用被破坏时,只要需要处理引用,就应该这样做
我不明白这个问题
PhantomReference
的目的是成为一个比常规定稿更灵活的替代方案。但是,为了使其工作,必须将引用排入队列,以使最终完成替换代码工作。(无法处理未排队的PhantomReference
。)相比之下
SoftReference
和WeakReference
对象通常在不排队的情况下很有用ReferenceQueue
API没有get()
方法,所以我猜您是在谈论PhantomReference
API。存在get()
方法的原因是为了与超类兼容。get()
被定义为返回null
的原因如下:(见javadoc。)
换句话说,这样做是为了使所指对象不可能“复活”
更新
事实上,所有
Reference
类都将在将Reference
排队之前清除引用对象。(实际上,GC本身直接执行此操作。)从ReferenceQueue
提取引用的应用程序代码不能使用get()
方法来标识(现在已删除!)参照物。他们必须以另一种方式去做;e、 g.基于参考对象的标识幻影引用的区别在于
get()
方法总是返回null
。(所以javadoc中的解释……不令人信服。)# 2 楼答案
也许,以下程序有点帮助:
在我的系统上,它打印
或
由于多线程,前两条消息的顺序有时会有所不同。有时,幻影引用报告在三次轮询后进入队列,这表明它花费的时间超过了指定的100毫秒
关键是
finalize
方法,则幻象引用在终结后进入队列,否则在对象再次变得不可访问后,幻象引用进入队列finalize()
方法的存在导致至少需要一个额外的垃圾收集周期来检测对象是否再次不可访问或幻影可访问由于超过99%的对象不需要最终确定,因此强烈建议所有JVM供应商检测
finalize()
何时未被重写或是“微不足道的”,即空方法或唯一的super.finalize()
调用。在这些情况下,应省略最终确定步骤。通过删除上面示例中的finalize()
方法,可以轻松地检查JVM中是否发生了这种优化。然后打印出来由于这两条消息同时排队并以任意顺序检索,因此这两条消息的顺序可能不同。但它们总是在一个gc循环后排队
值得注意的是,幻象引用不会自动清除,这意味着在对象的内存真正可以重用之前需要另一个垃圾收集周期,因此上面的示例需要至少三个周期(使用非平凡的
finalize()
方法)和两个周期(不使用)。Java9将改变这一点,自动清除幻影引用,因此在上面的示例中,需要两个周期完成,一个周期不完成,直到真正可以回收内存。准确地说,在这个简单的例子中,对象的内存永远不会被回收,因为程序会在这之前终止上面的代码还演示了参考API的一个预期用例。我们可以使用它来检测在我们完全控制下的代码中对象的可达性何时发生了变化,例如使用
main
方法中的循环。相反,finalize()
可以在任意时间由不同的、未指定的线程调用。该示例还显示,您可以从引用对象中提取信息,而无需使用get()
方法实际应用程序通常使用引用类的子类向它们添加更多信息。这就是
WeakHashMap.Entry
的情况,它扩展了WeakReference
并记住哈希代码和值。清理可以在正常的映射操作中完成,不需要任何线程同步。这对于finalize()
方法是不可能的,除了map实现不能将finalize()
方法推送到键类之外这意味着“比定稿更灵活”一词
WeakHashMap
演示了get()
方法是如何有用的。只要没有收集到密钥,它就会被报告为在映射中,并且可以在迭代所有密钥或条目时检索到已覆盖
PhantomReference.get()
方法,以始终返回null
,以防止应用程序可以恢复排队引用的引用对象。这是“虚拟引用未自动清除”规则的直接后果。这条规则本身是有问题的,它的初衷是在黑暗中。虽然规则将在下一个Java版本中更改,但我担心get()
将继续返回null
以向后兼容