回答:
一時停止が必要なのは、参照の更新だけではありません。「マークスイープ」の下に一般的にグループ化される標準アルゴリズムはすべて、オブジェクトグラフ全体がマークされている間は変更されないままであることを前提としています。修正(新しいオブジェクトの作成、参照の変更)を正しく処理するには、3色アルゴリズムなど、かなりトリッキーな代替アルゴリズムが必要です。包括的な用語は「コンカレントガベージコレクション」です。
ただし、圧縮後の参照の更新にも一時停止が必要です。そして、はい(たとえば、永続オブジェクトIDと実際のポインターへのハッシュテーブルを介して)を使用すると、一時停止を大幅に減らすことができます。望むなら、この部分をロックフリーにすることさえ可能かもしれません。低レベルの共有メモリ同時実行性と同じように正しく動作することは依然として難しいですが、動作しない根本的な理由はありません。
ただし、これには重大な欠点があります。余分なスペース(すべてのオブジェクトに対して少なくとも 2つの余分な単語)を使用することは別として、すべての逆参照をはるかに高価にします。属性を取得するような単純なことでも、ハッシュテーブル全体の検索が必要になります。パフォーマンスヒットは、インクリメンタルトレースよりもはるかに悪いと推定します。
コンピュータサイエンスのすべての問題は、別のレベルの間接参照によって解決できます。ただし、間接参照の層が多すぎるという問題を除きます。
アプローチは、ガベージコレクションの問題をすぐには解決せず、1レベル上に移動するだけです。そして、何の費用で!現在、すべてのメモリアクセスは、別のポインター逆参照を通過します。結果の場所をキャッシュすることはできません。その間に場所が変更された可能性があるため、常にオブジェクトIDを確認する必要があります。ほとんどのシステムでは、このインダイレクションは受け入れられません。世界を止めることは、総ランタイムコストが低いと想定されます。
私は、あなたの命題は問題を動かすだけで、解決するものではないと言いました。問題は、オブジェクトIDの再利用に関するものです。オブジェクトIDは現在、ポインターと同等であり、アドレスの数は限られています。プログラムの存続期間中に、INT_MAXを超えるオブジェクトが、たとえば次のようなループで作成されることが考えられます(特に32ビットシステム)
while (true) {
Object garbage = new Object();
}
各オブジェクトのオブジェクトIDをインクリメントするだけであれば、ある時点でIDが不足します。したがって、どのIDがまだ使用中で、どのIDが解放されているかを調べて、それらを再利用できるようにする必要があります。おなじみの音?今、私たちは正方形に戻っています。
あなたの考え方に誤りはありません。元のJavaガベージコレクターがどのように機能したかに非常に近いものを説明したところです。
元のJava仮想マシン[6]および一部のSmalltalk仮想マシンは、[6]でハンドルと呼ばれる間接ポインターを使用してオブジェクトを参照します。ハンドルを使用すると、ハンドルを使用すると、各オブジェクトへの直接ポインタが1つだけ存在するため、ガベージコレクション中にオブジェクトを簡単に再配置できます。ハンドルを介した間接的なオブジェクトへのその他すべての参照。このようなハンドルベースのメモリシステムでは、オブジェクトアドレスはオブジェクトの存続期間にわたって変化するため、ハッシュには使用できませんが、ハンドルアドレスは一定のままです。
ガベージコレクションされたオブジェクトのスペースと時間の効率的なハッシュ
SunのJava仮想マシンの現在の実装では、クラスインスタンスへの参照は、それ自体がポインタのペアであるハンドルへのポインタです。オブジェクトのメソッドを含むテーブルへのポインタと、オブジェクトのタイプ、およびオブジェクトデータ用のJavaヒープから割り当てられたメモリへのもう一方。
そのため、機能し、試行され、その非効率性が世代別マークおよびスイープシステムの開発につながりました。
Object.getHashCode()