1

fixnum の質問は、私が長い間疑問に思っていた別の質問を思い起こさせました。

ガベージ コレクションに関するオンライン資料の多くは、実行時の型情報を実装する方法について説明していません。したがって、私はあらゆる種類のガベージ コレクターについて多くのことを知っていますが、それらを実装する方法についてはあまり知りません。

fixnum ソリューションは実際には非常に優れており、どの値がポインターであり、どの値がポインターでないかが非常に明確です。型情報を格納するために一般的に使用される他のソリューションは何ですか?

また、 fixnum についても疑問に思います。それは、すべての配列インデックスで fixnums に制限されているということではありませんか? または、完全な 64 ビット整数を取得するための回避策はありますか?

4

2 に答える 2

4

基本的に正確なマーキングを実現するには、ポインターとして使用されている単語と使用されていない単語を示すメタデータが必要です。

このメタデータは、emacsと同様に、参照ごとに保存できます。言語/実装でメモリの使用をあまり気にしない場合は、参照を単語よりも大きくすることもできます(おそらく2倍の大きさ)。これにより、すべての参照に型情報とその1単語のデータを含めることができます。そうすれば、すべて64ビットの参照を犠牲にして、32ビットポインタのフルサイズのfixnumを使用できます。

または、メタデータを他のタイプ情報と一緒に保存することもできます。したがって、たとえば、クラスには、通常の関数ポインタテーブルと同様に、データレイアウトのワードごとに1ビットを含めることができます。これは、ワードにガベージコレクタが従う必要のある参照が含まれているかどうかを示します。言語に仮想呼び出しがある場合は、使用する関数アドレスをオブジェクトから計算する手段がすでに必要です。同じメカニズムを使用すると、使用するマーキングデータを計算できます。通常は、次の場所に秘密のポインターを追加します。実行時型を構成するクラスを指す、すべての単一オブジェクトの開始。明らかに、特定の動的言語では、ポイントされる型データは変更可能であるため、コピーオンライトである必要があります。

スタックは同様のことを行うことができます-コード自体のデータセクションに正確なマーキング情報を保存し、ガベージコレクターに、保存されたプログラムカウンター、スタック上のリンクポインター、および/またはスタックに配置されたその他の情報を調べさせます。スタックの各ビットがどのコードに関連しているか、したがってどのワードがポインターであるかを判別するためのコード。軽量の例外メカニズムは、コード内のtry / catchが発生する場所に関する情報を格納するために同様のことを行う傾向があります。もちろん、デバッガーもスタックを解釈できる必要があるため、これは他の多くのものと折りたたむことができます。ガベージコレクションが組み込まれている言語を含め、任意の言語を実装するためにすでに実行しているはずです。

ガベージコレクションは必ずしも正確なマーキングを必要としないことに注意してください。実際にそうであるかどうかに関係なく、すべての単語をポインタとして扱うことができます。ガベージコレクタの「すべてのビッグリスト」でそれを調べて、まだマークされていないオブジェクトを参照できるかどうかを判断します。したがって、それをそのオブジェクトへの参照として扱います。これは単純ですが、もちろんコストは、gcがルックアップに使用するデータ構造に応じて、「非常に遅い」と「非常に遅い」の間のどこかにあることです。さらに、整数が参照されていないオブジェクトのアドレスと同じ値を持っている場合があり、収集されるべきオブジェクトの束全体を保持することになります。したがって、このようなガベージコレクターは、これまでに収集された参照されていないオブジェクトについて強力な保証を提供することはできません。これは、おもちゃの実装や最初の作業バージョンには問題ないかもしれませんが、ユーザーに人気があるとは考えられません。

混合アプローチは、たとえば、オブジェクトの正確なマーキングを行う可能性がありますが、物事が特に毛むくじゃらになるスタックの領域のマーキングは行いません。たとえば、参照オブジェクトアドレスが通常のスタックスロットではなくレジスタにのみ表示されるコードを作成できるJITを作成する場合、OSがレジスタを格納したスタックの領域を不正確に追跡する必要がある場合があります。ガベージコレクターを実行するために、問題のスレッドのスケジュールを解除しました。これはおそらくかなり厄介なので、合理的なアプローチ(コードが遅くなる可能性があります)は、JITが使用しているすべてのポインター値のコピーを正確にマークされたスタックに常に保持することを要求することです。

于 2008-10-21T15:11:27.857 に答える