Soft/Weak/PhantomReferences的原理是清除对引用对象的引用,而引用对象已引用了跟踪的对象 [英] Rationale for Soft-/Weak-/PhantomReferences clearing references to objects which have reference to tracked object

查看:194
本文介绍了Soft/Weak/PhantomReferences的原理是清除对引用对象的引用,而引用对象已引用了跟踪的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

到那时,它将自动清除对该对象的所有幻像引用以及对任何可从该对象到达的任何其他幻像可访问对象的幻像引用.

At that time it will atomically clear all phantom references to that object and all phantom references to any other phantom-reachable objects from which that object is reachable.

让我感到困惑的部分是关于其他幻影可到达的对象.

The part which is confusing me is the one about the other phantom-reachable objects.

如果我正确理解,则说明此情况:
对象:

If I understand it correctly this describes this case:
Objects:

  • A
  • B

参考文献:

  • ->:强引用
  • -P->:幻影参考
  • ->: Strong reference
  • -P->: Phantom reference
-> A
-P-> B -> A

因此由于某种原因,垃圾收集器尚未确定B仅是幻像可到达的.现在,如果A变为幻影可到达的并且垃圾回收器检测到此情况,则需要(根据上面引用的文档)还清除对B的引用.

So for some reason the garbage collector has not determined yet that B is only phantom-reachable. Now if A becomes phantom-reachable and the garbage collector detects this, it is required (according to the doc quoted above) to also clear the reference to B.

文档为何有此要求?看来,如果其他供应商要开发JVM,那将是一个负担.

Is there any reason why the documentation requires this? It appears if other vendors were to develop a JVM this would be rather a burden.

推荐答案

我们首先要注意,这句话已经从软性和弱性引用文档中复制到Java 9幻像引用文档中,以适应更改在该版本中进行了修改,但不适用于幻影引用,因此对于软引用和弱引用都可以更好地解释其背后的原理.

We first have to note, that this sentence has been copied from the documentation for soft and weak references to the documentation for phantom references for Java 9, to accommodate changes made in that version, but is not a good fit for phantom references, so the rationale behind it is better explained for soft and weak references.

假设您遇到以下情况:

(weak)→ A
(weak)→ B (strong)→ A

从技术上讲,AB都是弱可及的,但是我们可以通过在任一弱引用上调用get()方法来更改此值,以检索对其引用对象的强引用.

technically, both A and B are weakly reachable, but we can change this be invoking the get() method on either weak reference, to retrieve a strong reference to its referent.

当我们对第一个弱引用执行此操作以检索对A的强引用时,对象B将保持弱可及性,但是当我们这样做以获得对B的强引用时,对象由于BA的引用很强,所以A也将变得很容易实现.

When we do this on the first weak reference, to retrieve a strong reference to A, the object B will stay weakly reachable, but when we do this to get a strong reference to B, the object A will also become strongly reachable, due to the strong reference from B to A.

因此,我们的规则是,如果清除对A的弱引用,则必须清除对B的弱引用,否则,可以通过以下方式检索对A的强引用尽管对A的引用较弱,但B已被清除.为了安全起见,它必须是原子发生的,因此没有可能的竞争条件允许在两个引用之间的间隙之间检索对B的引用.

Therefore, we have the rule that if the weak reference to A gets cleared, the weak reference to B must be cleared to, as otherwise, it would be possible to retrieve a strong reference to A via B despite the weak reference to A has been cleared. And to be on the safe side, it must happen atomically, so there’s no possible race condition allowing to retrieve a reference to B between the clearance of the two references.

如前所述,这与幻像引用的关联性较小,因为它们不允许检索引用,但没有理由将它们区别对待.

As said, this is of lesser relevance for phantom references, as those do not allow to retrieve the reference, but there is no reason to treat them differently.

这里的要点是,考虑到垃圾收集器的实际工作方式,这并不是实际的负担.它们必须遍历所有活动引用,即,高度可访问的对象以及所有未遇到的对象,都是消除后的垃圾.因此,在遍历过程中遇到弱引用时,它不会遍历引用对象,但要记住引用对象.一旦完成遍历,它将遍历所有遇到的参考对象,并查看参考对象是否已标记为可通过其他路径访问.如果没有,则清除参考对象并链接以使其入队.

The point here is, that this is not an actual burden, given how garbage collectors actually work. They have to traverse all live references, i.e. strongly reachable objects, and everything not encountered, is garbage per elimination. So when encountering a weak reference during a traversal, it won’t traverse the referent, but remember the reference object. Once it completed the traversal, it will run through all encountered reference objects and see whether the referent has been marked as reachable through a different path. If not, the reference object is cleared and linked for enqueuing.

以您的示例为例:

(strong)→ A
(weak)→ B (strong)→ A

在这里,无论对A的强引用如何,都很难达到B.当您删除对A的强引用时,B仍然是弱可及的,并且可能会被排队.从形式上讲,A现在可以弱访问,但是JVM永远不会在未检测到B弱访问的情况下也无法检测到它.检测A是弱可达的唯一方法是遍历从弱可达B开始的参考图.但是没有实现可以做到这一点.垃圾收集器只会清除对B的弱引用,仅此而已.

Here, B is weakly reachable regardless of the strong reference to A. When you eliminate the strong reference to A, B still is weakly reachable and may get enqueued. Formally, A is now weakly reachable, but the JVM will never detect that without detecting that B is weakly reachable too. The only way to detect that A is weakly reachable, would be by traversing the reference graph starting at the weakly reachable B. But no implementation does this. The garbage collector will simply clear the weak reference to B and that’s it.

这篇关于Soft/Weak/PhantomReferences的原理是清除对引用对象的引用,而引用对象已引用了跟踪的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆