V8がC++向けガベージコレクションライブラリを開発、メインスレッドのスイープ時間を最大50%削減

High-performance garbage collection for C++

V8チームが、ChromiumのBlinkで使われているC++ガベージコレクタOilpanをV8のライブラリとして公開する取り組みを紹介。並行スイープにより、デストラクタをメインスレッドで実行しつつ、メモリ回収をバックグラウンドで行う。Chrome M78ではメインスレッドのスイープ時間が25〜50%(平均42%)削減された。

C++はデストラクタに大きく依存しており、それはファイナライザとして実装されている。Oilpanは、開発者を支援しアプリケーションコード内のデータ競合を排除するため、ファイナライザをメインスレッドで実行することを強制する。
  1. MaxBarraclough

    これは非移動型のコレクタだ。C++のガベージコレクタの基準からすれば高性能かもしれないが、まともなJVMが実現できる性能には到底及ばないだろう。特にファイナライザ/デストラクタが存在しないことを考えればなおさらだ。

    Ron Pressler(HNではpronとして知られている)が最近強調しているように、[0] 移動型ガベージコレクタの「スイープ」フェーズは、ヒープ内の死んだオブジェクトのサイズや数に影響されない(少なくともファイナライザがない典型的なケースでは)。しかし、ここではそうではない(フリーリストを使っている)し、どのC++ GCでもそうだ。

    すべてのデストラクタを同じスレッドで実行するという方針も、たとえ正当な理由があったとしても、「高性能」なアーキテクチャにはあまり見えない。

    それでも、これは素晴らしいプロジェクトだ。私はこれが結構気に入っている:

    > OilpanはClangプラグインを使って、数あることの中でも特に、オブジェクトの破棄中にヒープオブジェクトがアクセスされないことを静的に検証する

    これはよく理解できない:

    > OilpanはC++で書かれたガベージコレクタで、C++のメモリを管理するために、クロスコンポーネントトレーシングを使ってV8に接続でき、絡み合ったC++/JavaScriptオブジェクトグラフを1つのヒープとして扱う。

    どういう意味で1つのヒープとして扱われるのか? V8がJavaScriptヒープに移動型GCを使っていることを考えれば、どうしてそんなことが可能なのか? 単に、C++オブジェクトがJavaScriptオブジェクトを参照し、その逆も可能にする何らかのメカニズムがあるというだけのことなのか?

    [0] https://youtu.be/xr73mR7ii9M?t=1081 Principles of Memory Management in Java, September 2026

  2. OskarS

    これを読んでいると、C++26の静的リフレクションがこのようなシステムの人間工学をどれだけ改善できるのか気になる。例えば、クラスに特定の属性をタグ付けすれば、Trace()関数を自動生成できるのか? Member<>テンプレートを使って他のGCクラスを自動的にラップできるのか? Trace()関数の実装は可能だと思う(CRTPを使うGarbageCollected<>基底クラスでやるんだろう?)が、型をラップするのは無理かもしれない。リフレクションでフィールドの型をそのように変更できるかどうかはわからない。

  3. d_finch

    興味深いが、やはりC++のやり方としては`std::shared_ptr`と注意深い所有権管理だと思う。GCは別のランタイム依存を追加するように感じる。

この日のほかの記事

2026-09-15