10

最新のガベージ コレクター (CLR、JVM など) は、どのヒープ オブジェクトがスタックから参照されているかを判断するためにどのような手法を使用していますか?

具体的には、VM は、スタックが開始する場所を認識してから、ヒープ オブジェクトへのすべてのローカル参照を解釈するように戻すにはどうすればよいでしょうか?

4

3 に答える 3

3

Java (およびおそらく CLR) では、バイトコードはオブジェクトとプリミティブの情報で型付けされます。その結果、バイトコードには、各スタック フレームのどの変数がオブジェクトで、どの変数がプリミティブであるかを記述するデータ構造があります。GC がルート セットをスキャンする必要がある場合、GC はこれらのStackMapTablesを使用して参照と非参照を区別します。

CLR と Java は正確なコレクターであるため、このようなメカニズムが必要です。スタック上のすべてのオフセットを可能なポインターとして扱うboehm コレクターのような保守的なコレクターがあります。値 (ポインターとして扱われる場合) がヒープへのオフセットであるかどうかを確認し、そうである場合は、それを有効としてマークします。

于 2012-10-06T14:03:11.227 に答える
0

1996 年 8 月の Artima の記事Java 's Garbage-Collected Heapを参照してください。特に2ページ目

ガベージ コレクション アルゴリズムは、2 つの基本的なことを行う必要があります。まず、ガベージ オブジェクトを検出する必要があります。次に、ガベージ オブジェクトによって使用されたヒープ領域を再利用し、プログラムで使用できるようにする必要があります。通常、ガベージ検出は、一連のルートを定義し、ルートからの到達可能性を判断することによって行われます。実行中のプログラムがオブジェクトにアクセスできるルートからの参照のパスがある場合、オブジェクトは到達可能です。ルートは、プログラムから常にアクセス可能です。ルートから到達可能なオブジェクトはすべてライブと見なされます。到達できないオブジェクトは、今後のプログラム実行に影響を与えることができないため、ガベージと見なされます。

JVM では、ルート セットは実装に依存しますが、ローカル変数には常にオブジェクト参照が含まれます。JVM では、すべてのオブジェクトがヒープ上に存在します。ローカル変数は Java スタック上に存在し、実行の各スレッドには独自のスタックがあります。各ローカル変数は、オブジェクト参照か、int、char、float などのプリミティブ型です。したがって、JVM ガベージ コレクション ヒープのルートには、すべてのスレッドのスタック上のすべてのオブジェクト参照が含まれます。ルートの別のソースは、ロードされたクラスの定数プール内の文字列などのオブジェクト参照です。ロードされたクラスの定数プールは、クラス名、スーパークラス名、スーパーインターフェース名、フィールド名、フィールド署名、メソッド名、メソッド署名など、ヒープに格納された文字列を参照する場合があります。

ルートによって参照されるすべてのオブジェクトは到達可能であるため、ライブ オブジェクトです。さらに、ライブ オブジェクトによって参照されるすべてのオブジェクトにも到達可能です。プログラムは到達可能なすべてのオブジェクトにアクセスできるため、これらのオブジェクトはヒープ上に残す必要があります。到達できないオブジェクトは、プログラムがそれらにアクセスする方法がないため、ガベージ コレクションされる可能性があります。

この記事では、参照カウント コレクター、トレース コレクター、コンパクト コレクター、コピー コレクターなど、さまざまなガベージ コレクション戦略について引き続き説明します。


この記事は古いものですが、今日でも適用されます。あまり変わっていません。さまざまなコレクション戦略のパフォーマンスが向上しましたが、新しい大きな進歩はありません。

たとえば、Oracle HotSpot JVM には、新しいガベージ ファースト ガベージ コレクタがあります。これは、マルチコア プロセッサと大きなヒープ サイズ向けのパフォーマンス調整を備えたコピー コレクタです ( G1 ガベージ コレクタの詳細については、この回答を参照してください)。

于 2012-05-30T12:35:41.027 に答える
0

CoreCLR をオープン ソースにした直後に .Net チームが投稿した、このトピックに関する興味深いドキュメント: Stack Walking

于 2015-02-12T15:53:27.973 に答える