私は現在、世代別ガベージコレクターに取り組んでいます。これは、最新のオブジェクトのみがトラバースされ、生き残ったオブジェクト (= 既知のルートから到達可能) が古い世代に昇格されることを意味します。オブジェクトが同じ世代または古い世代の他のオブジェクトを指している場合、これは問題なく機能します。ただし、古いオブジェクトが新しいオブジェクトを指している場合、新しいオブジェクトのみがトラバースされるため、ポイントされたオブジェクトが正しく収集されません。これを回避するために、そのようなオブジェクトは各 GC フェーズで明示的にマークされ、トラバースされます。
構造上、不変オブジェクトは常に既存のオブジェクトを指しているため、このような「親」オブジェクトは明らかに変更可能です。したがって、「親」になるには、昇格後にオブジェクトを変更して、新しいオブジェクトを指すようにする必要があります。
古い世代のどのオブジェクトが若い世代を指しているのかを知るために、メモリの変化を透過的に監視する方法を探しています。そのために、メモリ保護とシグナル/例外処理を使用します。メモリページは読み取り専用に設定されているため、書き込まれるたびにシグナル/例外が発生します。その場合、メモリ保護を読み取り/書き込みに戻し、さらに処理するためにアドレスをどこかに記録し、応答時に責任のあるコードを返します例外のため、正常に再開します。そうすれば、GC がトリガーされたときに、トラバースする可能性のある親を見つけるためにどこを見ればよいかがわかります。
Linux では、mprotect/SIGSEGV シグナル処理を組み合わせて使用します。Windows では、VirtualProtect を使用する予定ですが、SIGSEGV 処理に相当するものは見つかりませんでした。だから私の質問:
Windowsでそれをどのように行いますか?例外処理 API はかなり混乱しているようです。
この簿記をすべて行う必要がないように、どのメモリ領域が変更されるかを知るより良い方法はありますか?
私のコードはプレーンな C で書かれています。現在、変更されたオブジェクトを明示的にマークする呼び出し元コードが必要ですが、これは面倒でエラーが発生しやすいため、透過的な方法を探しています。
前もって感謝します、フレッド