A
インターフェイスを実装するクラスがあり、インターフェイスが期待される場所、たとえばスレッドにI
渡すと、GC はクラスのインスタンスをガベージ コレクションできなくなりますか? あると思いますが、どうすればいいのでしょうか?public static 内部クラスを作成するとしますか?I
A
4 に答える
ここでは、オブジェクトへの参照のタイプは重要ではありません。オブジェクト、そのスーパータイプ、またはインターフェイスと同じタイプである可能性があります。それはまったく問題ではありません。
重要なのは、オブジェクトがルート コンテキストから到達可能かどうかです。オブジェクトが有効な参照を持つまで (その参照の型に関係なく)、ガベージ コレクションは行われません。
実際、オブジェクトはそれを直接参照していない場合もあります。以下で説明するように、ルート コンテキストから間接的に到達できる場合 (GC ルートからのツリー トラバーサル)、GC の対象にはなりません。
ルート コンテキストとは
プログラムがルートで作成するすべてのオブジェクト、つまり直接のようなオブジェクトParent p = new Parent();
が呼び出されGC Roots
、まとめてルート コンテキストを形成します。ガベージ コレクションの対象となる GC ルートはありません。次のような新しいChild
オブジェクトを作成すると
p.setChild(new Child());
次に、Child
オブジェクト (ただし GC ルートではない)Parent
は p を介してルート コンテキストからアクセスできるようになるため、ガベージ コレクションの対象にはなりません。ここで、現在の子を次のように置き換えると
p.setChild(new Child()); // old child replaced
古い子オブジェクトは孤立し (ルート コンテキストから到達できなくなります)、ガベージ コレクションが発生します。したがって、参照型はオブジェクトのガベージ コレクションには関係がないことがわかります。
そして、このトピックを完成させるために:分離されたオブジェクトの島(それらは相互に参照を保持している場合がありますが) は、ルート コンテキストから到達できないため、ガベージ コレクションを取得します。
いいえ、オブジェクトへの参照がまだスレッド スタックに存在するため、インスタンスのガベージ コレクションは行われません。
インターフェイスの実装に WeakReference を保持することですべてを解決しました。