11

収集時に、ガベージ コレクターはすべてのライブ オブジェクトを別のメモリ空間にコピーし、プロセス内のすべてのガベージ オブジェクトを破棄します。新しいスペースにコピーされたオブジェクトへのフォワード ポインターは、オブジェクトの「古い」バージョンにインストールされ、コレクターがオブジェクトへの残りのすべての参照を正しく更新し、同じオブジェクトを誤って 2 回コピーしないようにします。

これは明らかに、ストップ・ザ・ワールド・コレクターにとって非常にうまく機能します。ただし、stop-the-world では一時停止時間が長いため、現在、ほとんどのガベージ コレクターはミューテーター スレッドがコレクターと同時に実行されることを許可し、ミューテーターを短時間だけ停止して初期スタック スキャンを実行します。

では、コレクターは、オブジェクトの「古い」バージョンが、コピー中/コピー後にミューテーターによってアクセスされないようにするにはどうすればよいでしょうか? ミューテーターは何らかの読み取りバリアを使用してフォワード ポインターをチェックできると思いますが、変数が頻繁に読み取られるため、これはコストがかかるようです。

4

3 に答える 3

3

AzulのGenerational Pauseless Garbage Collector に実装されているLoaded Value Barrierは、この問題の解決策の例です。これについては、2011 年初頭に InfoQ に投稿されたThe Azul Garbage Collectorという記事で読むことができます。

于 2013-01-21T09:44:53.170 に答える
2

読み取りバリアまたは書き込みバリアを使用する必要があります。あなたは明らかにすでに読み取り障壁を認識しているので、私はそれらに入ろうとはしません.

ライター バリアが機能するのは、書き込みが発生しないようにしている限り、誰かがデータの古いコピーまたは新しいコピーにアクセスするかどうかを気にしないためです。書き込みバリアを設定し、データをコピーしてから、ポインターの調整を開始します。コピーが作成された後は、誰かがデータの古いコピーを読み取るか新しいコピーを読み取るかはあまり気にしません。これは、書き込みバリアによってそれらが同一であることが保証されるためです。ポインターの調整が完了すると、すべてが新しいデータで機能するようになるため、書き込みバリアを取り消します。

ページ保護ビットを使用してメモリの領域を読み取り専用としてマークし、かなり標準的なハードウェアで書き込みバリアを作成する作業がいくつか行われています。少なくとも私が最後に調べたときは、これはまだ概念実証の段階にあり、機能していましたが、実用的であるには遅すぎました。

于 2013-01-21T17:29:11.780 に答える
2

免責事項: これは JavaShenandoah GCのみに関連しています。

あなたの理由はShenandoah! たとえば、ここにいくつかの詳細があります。

少し前までは、すべてのプリミティブ型と参照型Shenandoahの書き込みバリアと読み取りバリアがありました。読み取りバリアは、実際には、あなたが想定しているように、 を介した単一の間接化でした。それらは書き込み (はるかに複雑なバリア) と比較してはるかに多いため、これらの読み取りバリアは、それらよりも (時間的に累積的に) 高価でした。これは、これらが非常に多いという唯一の事実と関係がありました。forwarding pointerwrite

しかし、バリアが実装された jdk-13 で状況が変わりました。Load Referenceしたがって、ロードのみがバリアを持ち、書き込みは通常の方法で行われます。考えてみると、これは完全に理にかなっています。Object フィールドに書き込むには、最初にそのオブジェクトを読み取る必要があります。そのため、バリアが「スペースへの不変条件」を保持している場合、常に最新のものから読み取ることになります。オブジェクトの正しいコピー。で読み取りバリアを使用する必要はありませんforwarding pointer

于 2019-12-02T15:04:34.783 に答える