最初に注意しなければならないのは、この文は Java 9 のファントム参照のドキュメントへのソフト参照とウィーク参照のドキュメントからコピーされたものであり、そのバージョンで行われた変更に対応するためのものですが、ファントム参照には適していないため、その背後にある理論的根拠は、ソフト参照と弱い参照についてよりよく説明されています。
次の状況があるとします。
(weak)→ A
(weak)→ B (strong)→ A
技術的には、 と の両方AにB弱い到達可能性がありますがget()、どちらかの弱い参照でメソッドを呼び出して、その指示対象への強い参照を取得することで、これを変更できます。
への強い参照を取得するために最初の弱い参照でこれを行うとA、オブジェクトBは弱い到達可能のままになりますが、への強い参照を取得するためにこれを行うと、からの強い参照によりB、オブジェクトAも強く到達可能になります。BにA。
したがって、 への弱参照Aがクリアされた場合、 への弱参照をクリアする必要があるというルールがあります。そうしないと、への弱参照がクリアされたにもかかわらず、via へBの強参照を取得できてしまうからです。安全のために、これはアトミックに発生する必要があるため、2 つの参照のクリアランスの間に参照を取得できる競合状態はありません。ABAB
前述のように、ファントム参照では参照を取得できないため、これは関連性が低くなりますが、異なる方法で処理する理由はありません。
ここでのポイントは、ガベージ コレクターが実際にどのように機能するかを考えると、これは実際の負担ではないということです。それらはすべてのライブ参照、つまり強力に到達可能なオブジェクトをトラバースする必要があり、遭遇しないものはすべて削除ごとにガベージです。そのため、トラバーサル中に弱い参照に遭遇すると、参照対象をトラバースしませんが、参照オブジェクトを記憶します。トラバーサルが完了すると、遭遇したすべての参照オブジェクトを実行し、参照先が別のパスから到達可能としてマークされているかどうかを確認します。そうでない場合、参照オブジェクトはクリアされ、エンキューのためにリンクされます。
あなたの例に対処するには:
(strong)→ A
(weak)→ B (strong)→ A
ここで、Bへの強い参照に関係なく、 は弱く到達可能Aです。への強い参照を削除してもA、 はBまだ到達可能性が低く、エンキューされる可能性があります。正式にAは、現在は弱い到達可能性がありますが、JVM はそれが弱い到達可能性であることを検出しない限り、決してそれを検出しBません。弱い到達可能性を検出する唯一の方法Aは、弱い到達可能性から始まる参照グラフをトラバースすることですB。しかし、これを行う実装はありません。ガベージ コレクターは、弱い参照を単純にクリアしBます。それだけです。