-
28-10-2019 - |
質問
そのルーツガベージコレクション
私の定義のルートとして"参照するプログラムへのアクセス"の定義のライブはオブジェクトに使用されている、地元の変数,静的変数となります。
I mほか別の違いをルートとライブオブジェクト。
何のパスルート?どのようなルートや生き物。
できる人凝?
解決
メモリ内のオブジェクトをツリーと考えると、「ルーツ」がルートノードになります。すべてのオブジェクトはプログラムですぐにアクセスできます。
Person p = new Person();
p.car = new Car(RED);
p.car.engine = new Engine();
p.car.horn = new AnnoyingHorn();
4つのオブジェクトがあります。人、赤い車、そのエンジン、ホーン。参照グラフを描く:
Person [p]
|
Car (red)
/ \
Engine AnnoyingHorn
そして、あなたは終わるでしょう Person
木の「ルート」で。ローカル変数が参照しているため、ライブです。 p
, 、プログラムはいつでも使用するために使用する可能性があります Person
物体。これは、他のオブジェクトにも当てはまります p.car
, p.car.engine
, 、など
以来 Person
そして、それに再帰的に接続された他のすべてのオブジェクトはライブであり、GCがそれらを収集した場合に問題があります。
ただし、しばらくして以下が実行される場合は、次のように考えてください。
p.car = new Car(BLUE);
グラフを再描画します:
Person [p]
|
Car (blue) Car (red)
/ \
Engine AnnoyingHorn
今 Person
介してアクセス可能です p
そして青い車は通り抜けます p.car
, 、しかし、赤い車やその部品に再びアクセスできる方法はありません - それらはライブルートに接続されていません。安全に収集することができます。
したがって、それは本当にすべての出発点(すべてのローカル変数、グローバル、statics、他のスレッド、スタックフレームのすべて)を取得することです - すべてのルート - すべての参照に従って、すべての「ライブ」オブジェクトのリストを作成するために再帰的に続きます。使用されており、削除に適さないオブジェクト。他のすべてはゴミで、集められるのを待っています。
他のヒント
GC(ガベージコレクター)ルーツは、ゴミコレクターに特別なオブジェクトです。ゴミコレクターは、GCルーツではなく、GCルーツからの参照によってアクセスできないオブジェクトを収集します。
GCルーツにはいくつかの種類があります。 1つのオブジェクトは、複数の種類のルートに属することができます。ルートの種類は次のとおりです。
- クラス - システムクラスローダーによってロードされたクラス。そのようなクラスは決して降ろすことはできません。静的フィールドを介してオブジェクトを保持できます。 java.lang.classの対応するインスタンスが他の種類のルーツである場合を除き、カスタムクラスローダーによってロードされたクラスはルーツではないことに注意してください。
- スレッド - ライブスレッド
- スタックローカル - javaメソッドのローカル変数またはパラメーター
- JNIローカル - ローカル変数またはJNIメソッドのパラメーター
- JNIグローバル - グローバルJNIリファレンス
- 使用済み - 同期のためのモニターとして使用されるオブジェクト
- JVMが開催 - JVMがその目的でGarbage Collectionから保有するオブジェクト。実際、そのようなオブジェクトのリストはJVMの実装に依存します。既知のケースは次のとおりです。システムクラスローダー、JVMが知っているいくつかの重要な例外クラス、例外処理のためのいくつかの事前に割り当てられたオブジェクト、およびクラスのロードプロセスにあるときのカスタムクラスローダー。残念ながら、JVMはそのようなオブジェクトに追加の詳細をまったく提供していません。したがって、特定の「JVMが保持している」がどのケースであるかを決定するのはアナリスト次第です。
(クレジット yourkitのウェブサイト)
Yourkitで言及されていないのは、最終化を待っているオブジェクトがGCが実行されるまでルーツとして保持されるという事実です finalize()
方法。これにより、大型グラフの一時的な保持がやや予想外に保持される可能性があります。一般的な経験則は、ファイナライザーを使用することではありません(ただし、それは別の質問です)。
根やごみ収集の根は、 常に到達可能です. 。オブジェクトが常に到達可能である場合、ゴミ収集の対象はありません。したがって、根は常に収集の対象外です。これは、ヒープ上の他のすべてのオブジェクトの到達可能性が決定される場所の最初のオブジェクトセットです。
ゴミコレクションから到達可能なヒープ上の他のオブジェクトは、 ライブオブジェクト, 、および収集の資格がありません。到達不可能なオブジェクトは、再生のためにマークできます。
.NETプラットフォームよりもJavaを知っているので、1つだけを話します。 Javaプラットフォームでは、GCルーツは実際に実装に依存しています。ただし、ほとんどのランタイムでは、GCルーツはスタック上のオペランド(現在スレッドで使用されているため)およびクラスのクラス(静的)メンバーである傾向があります。到達可能性は、ほとんどのJVMでこれらのオブジェクトから計算されます。 JNI呼び出しで使用されるローカルパラメーターとオペランドがルートセットの一部と見なされ、到達可能性の計算にも使用される他のケースがあります。
これが、ルート(セット)とライブオブジェクトとは何かについて、長引く疑問をクリアすることを願っています。
の IBMウェブサイト リストは以下のとしてGC。
場合がありますので、ご注意これらの人工構築によるメモリー分析装置も重要なのまでヒープダンプ
システムクラス
クラスになりましたが、ブートストラップローダ、システムクラスローダを使用します。例えば、このカテゴリを含むすべてのクラスのrt.jar ファイル(一部のJava runtime environment)等のjava.util.* パッケージです。
JNI地
局所変数をネイティブコードは、例えばユーザー定義のJNIコードは、JVM内のコードです。
JNIグローバル
グローバル変数のネイティブコードは、例えばユーザー定義のJNIコードは、JVM内のコードです。
スレッドブロック
オブジェクトを参照されたからアクティブスレッドブロックです。
スレッド
走行中のthread.
忙しいモニター
あるというのwait()または通知()メソッド、またはそのおそれのある同期、呼び出しによる同期(Object)メソッドまたは入力する同期方法です。このメソッドは、静的かつ根源であるクラスは、そうでない場合はオブジェクトです。
Java地
地元の変数となります。例えば、入力パラメーター又は現地で作成したオブジェの方法がいまだにスタックのねじになります。ネイティブスタック
入力と出力パラメータをネイティブコードは、例えばユーザー定義のJNIコードは、JVM内のコードです。多くの方法がネイティブパーツのオブジェクトとして取り扱い方法でパラメータとなるごみ収集。例えば、パラメータファイル、ネットワーク、I/Oまたは反射す。
Finalizer
オブジェクトはキュー待ち、finalizer。
Unfinalized
オブジェクトは、ファイナライズメソッドではないと考えられなかった決定、なにfinalizerます。
到達不能
であるオブジェクトの到達不能その他のルートが印としてルートによるメモリー分析装置のオブジェクトを含めることができ、分析していきます。
到達不能なオブジェは多くの結果を最適化でのガベージコレクションアルゴリズムです。例えば、オブジェクトが候補者はガベージコレクションが、小さなゴミの収集を行うことができるのではなく高い。この場合、オブジェクトができないごみは、収集したが残るとして、到達不能なオブジェクトです。
デフォルトでは、到達不能なオブジェを除くメモリ装置を解析し、ヒープのダンプこれらのオブジェクトのためのヒストグラム●ドミネーターツリー、またはクエリの結果.この設定を変更することができ行動をクリックファイル>環境設定...>IBM診断ツールのためのJavaメモリ装置、その選択には到達不能なオブジェクリックします。
Javaスタックフレーム
Javaスタックフレーム、ローカル変数.このタイプのごみ収集ルートが発生する設定した場合の嗜好を扱うJavaスタックフレームとしてオブジェクト。詳細については、Javaの基本要素:スレッドのスレッドのスタックます。
不明
オブジェクトのルートタイプです。一部の堆積場などのIBM携帯ヒダンプ(.博士)ファイルがないルート情報です。この場合、メモリー分析装置のパーサマーオブジェとしてインバウンドの参照、または到達不能その他のルートとして不明である。この動作を確保したメモリー分析装置を保持すすべてのオブジェクトにダンプ
Javaでは、スレッドがルートオブジェクトだと思います。すべてのライブオブジェクトは、ライブスレッドに戻ることができます。たとえば、静的オブジェクトはクラスによって参照されます。クラスはクラスローダーによって参照されます。クラスローダーは、そのクラスのインスタンスによって参照される別のクラスで参照されます。ライブスレッドによって。 (注意してください、クラスはgc'edすることができます、それらはルーツになることはできません)
また、すべてのスレッドの「実際の」ルートを考慮することもできますが、それは標準のJavaの領域から外れています。それが何であるか、そしてそれがすべてのスレッドをどのように参照するかは言えません。