私はBoehm GCをチェックしました。 C/C++用のGCです。Boehm GCはCプログラムでどのように動作しますか?
私はマークアンドスイープアルゴリズムを知っています。私が好奇心を持っているのは、Cメモリ全体のポインタだけを取り出す方法です。私のCメモリの理解は単なるバイト配列です。メモリ内の値がポインタかどうかを判断することは可能ですか?
私はBoehm GCをチェックしました。 C/C++用のGCです。Boehm GCはCプログラムでどのように動作しますか?
私はマークアンドスイープアルゴリズムを知っています。私が好奇心を持っているのは、Cメモリ全体のポインタだけを取り出す方法です。私のCメモリの理解は単なるバイト配列です。メモリ内の値がポインタかどうかを判断することは可能ですか?
Boehm GCは、すべてがポインタであることを前提とした保守的なコレクタです。これは、偶然、ヒープ内のアドレスの値を持つ整数のような誤った正の参照を見つけることができることを意味します。その結果、一部のブロックは、非保守的なコレクタよりもメモリに長く滞留することがあります。
ここBoehm's pageから説明は次のとおり
ガベージコレクタは、修飾 マークスイープアルゴリズムを使用します。
- 調製各オブジェクトが関連付けられているマークビットを有している。概念的には メモリ割り当ての一部として時々行われる 4つのフェーズに概ね動作します。すべてのオブジェクトが潜在的に到達不能であることを示す ビットをすべてクリアします。
- マークフェーズマーク変数のポインタを使用して到達可能なすべてのオブジェクトをマークします。 コレクタには、ヒープ内のポインタ 変数の場所に関する実際の情報はありません。 静的データ領域、スタック、および レジスタは潜在的に ポインタを含んでいます。 がヒープ内のアドレスを表す任意のビットパターン コレクタによって管理されるオブジェクトは、 がポインタとして表示されます。クライアント プログラムが、 コレクタに利用可能なヒープオブジェクトレイアウト 情報を作成していない限り、 に見つかったヒープオブジェクトはすべて同様にスキャンされた変数から再び到達可能です。
- 掃引フェーズアクセス不可能な、したがってマークされていない オブジェクトのヒープをスキャンし、再利用のために適切な空きリストに返します。この は実際には別のフェーズではありません。さらに 非インクリメンタルモードの場合 の操作が通常 で実行され、割り当て中に が空の空きリストが検出されます。したがって、 掃引フェーズは、 と接触する可能性は非常に低く、 はすぐ後にタッチされていなかったはずです。
- ファイナライズフェーズ のファイナライズのために登録された到達不能オブジェクトは、コレクタの外側で のファイナライズを行うためにエンキューされます。
また、ベームGCはマークアンドスイープアルゴリズムのためのポイントを開始している「ルーツ」のセットを与える必要があることを知っている必要があります。スタックとレジスタは自動的にルートになります。明示的にグローバルポインタをルートとして追加する必要があります。
編集:コメントでは、一般的に保守的なコレクターについてのいくつかの懸念が指摘されました。コレクタへのヒープポインタのように見える整数は、メモリが解放されないようにする可能性があります。これはあなたが考えるかもしれないほど大きな問題ではありません。プログラム内のスカラー整数は、カウントとサイズに使用され、かなり小さい(ヒープポインタのようには見えない)。ほとんどの場合、ビットマップ、文字列、浮動小数点データ、またはそのようなものを含む配列に問題が発生します。 Boehm GCでは、GC_MALLOC_ATOMIC
のブロックを割り当てることができます。これは、ブロックにポインタが含まれないことをコレクタに示します。 gc_typed.hを見ると、ブロックのどの部分にポインタが含まれるかを指定する方法もあります。つまり、ポインタの書き換えが安全でないため、コレクション中にメモリを安全に動かすことができないという基本的な制限があります。つまり、断片化の軽減やキャッシュのパフォーマンスの向上など、圧縮のメリットは得られません。
lolこれが本当であれば、このアルゴリズムは普通のガベージーです。xD – codymanix
コンパイラの助けを借りて(ポインタの場所を教えて)得ることができます。 –
+1。非常に明確な答え。 –