ガベージコレクターがヒープ内のオブジェクトを圧縮すると、スタック上の参照が変更されますか?


18

これは単純な質問のように思えますが、このテーマについて多くのことを読んだ後でも、決定的な答えは見つかりませんでした(おそらくそれはとても単純だからです)。

私の質問はこれです:ガベージコレクターがヒープ内のオブジェクトを圧縮すると、スタック内のオブジェクトへの参照はどのように更新されますか?私は2つの可能な解決策を考えることができます:

  1. スタック(およびヒープ内の参照)を調べて、オブジェクトの新しい場所を指すように参照を更新します。引っ越しに例えると、これはあなたの住所を持っている人に手紙を送り、新しい住所で住所録を更新するように頼むようなものです。
  2. 何らかのルックアップテーブルを提供します。これは、ローカルの郵便局に転送先を残すようなものです。

ガベージコレクターは主にこれら2つの方法のいずれかを使用しますか?他の方法?どちらも?



@StevenBurnapは私が間違っていれば私を修正しますが、あなたがリンクしたスレッドには決定的な答えがなかったと信じています。彼らはこの正確な質問についても推測しているようでした。誤読している可能性があります。質問への回答を提供してくれたとしても、気にしないのであれば、将来のSEユーザー(および私自身)に回答をここに要約すると役立つと思います
-todorojo

あなたが話していることを表す用語は、「移動するガベージコレクター」です。率直に言って、それらがどれほど一般的に使用されているのかわかりません。
ロボット

回答:


9

これに関する特定の専門知識はありませんが、私の理解では、最初の方法が一般的に使用されるということです。

ガベージコレクターは、とにかくスタックを分析して、ヒープ内のどのものがスタックから参照されているかを見つける必要があります。何かを移動することを決定したら、とにかく参照を修正する必要があり、その時点でヒープとスタックを区別する理由はありません。

原則として、ルックアップテーブルアプローチが機能します。ただし、すべてのポインターアクセスには2つのステップが必要になります。これは、通常の実行時間に大きなパフォーマンスの影響を与えます。特に、多くの小さなオブジェクトのユースケース用。(これは、最先端のGCプログラムが通常参照カウントを上回るケースです。)


3
私は、GC が必要としない限り、おそらくヒープ上で物を動かさないようにしようと思うと付け加えます。今日のマルチプロセッサの世界では、これらの参照を使用するプログラムの実行中にヒープ上の何かへのすべての参照を更新する必要がある場合、同期の悪夢に違いありません。ルックアップテーブルはこれを簡素化しますが、それは標準ではなく例外だと思うので、ほとんどのGCはおそらくいくつかの参照をロックし、メモリを移動してから参照を更新する必要があります。+1興味深い質問、+ 1良い答え。
グレンペターソン

3
@GlenPeterson多くのGCは実際にヒープ上で物事を動かさないため、この問題に直面しません。しかし、定義による圧縮GCは、ライブオブジェクトをメモリの最適化に移動します。
btilly

@GlenPetersonヒープ上を移動することは大きな同期の痛みであることがよく観察されますが、GCの圧縮はこれにより実行中のプロセスに大きな波及効果がありますが、これは見過ごされがちです。これは、大きなヒープの更新によって圧縮が長いミューテックスを保持するのを回避するために、オブジェクトをできるだけ短命にするためにできる限りのことをするように言われる最大の理由です。このようなものの動作の無知は、GC Freakout Modeと呼ばれているものにつながる可能性があります。
ジミー・ホッファ

2
元のMacintoshとPalm OSはどちらも、メモリ管理にルックアップテーブルアプローチを使用していました。テーブルへのポインタは、ハンドルと呼ばれていました。再配置するGCは、移動するオブジェクトへのすべての参照の絶対的なポジショニングの所在を知る必要があります。そのような目的で単一のテーブルを使用すると、物事が大幅に簡素化されます。
supercat
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.