📑

GoのGC 2025

に公開

はじめに

こんにちは、AI Shift開発チームの由利です。
この記事はAI Shift Advent Calendar 2025の13日目の記事になります。

GoGC 最新版 - GreenTea

今年Go1.25が登場しましたが、これに実験的に載せられている最新GCについて初心者向けにご紹介しようと思います。
これはGreenTeaと呼ばれ、ビルド時に GOEXPERIMENT=greenteagc を指定することで利用することができます。

この GreenTea は、Google 内部での大規模ワークロードに対するテストなどで GC オーバーヘッドを 10〜最大 40% 程度削減 できたと報告されており、従来 GC の弱点をハードウェアレベルから解消するアプローチが取られています。

また、Go チームの公式アナウンスでは Go 1.26 でデフォルト GC として採用される予定 とされています(あくまで予定)。

GreenTeaがフォーカスするもの

それでは早速中身を見ていきましょう。
GCのコストは下記の式で表されます。

GCの総コスト = GCサイクルの回数 * 1GCサイクルあたりの平均コスト

GCサイクルの回数・頻度に着目した設定値としてGOGC、GOMEMLIMITの設定値が挙げられます。
これらを適切に設定することでGCサイクル頻度とヒープメモリサイズのバランスを取ることが出来ます。
(これらの設定値については今回は説明を割愛します)

今回のGreenTeaでは「1GCサイクルあたりの平均コスト」に焦点を当てて改善しています。
特に GC の中でも最も重い mark フェーズ(到達可能オブジェクトの探索) を大幅に効率化するアプローチが採られています。

mark-sweep アルゴリズム - GoのGCロジック再訪

その前に簡単にGoのGCロジックをおさらいしておきましょう。
Go の GC は「トレース型」であり、基本的には以下の流れで動作します。

  1. mark フェーズ
    ルート(スタックやグローバル変数など)からたどれるオブジェクトを探索し、使用中であることをマークします。
  2. sweep フェーズ
    mark が付いていないオブジェクトを解放し、ヒープ領域を再利用可能にします。
  3. 上記を繰り返す(Go の場合は大部分が並行で行われる)

このうち、最もコストが高く CPU キャッシュ効率に影響するのが mark フェーズです。

従来アルゴリズムとGreenTeaの違い

GreenTeaではこのmarkフェーズの効率化に注目しました。
GreenTea が改善したのは 「どの粒度で mark の対象を扱うか」 です。

従来アルゴリズムはオブジェクトに注目してmarkを実行していきます。
オブジェクト同士のポインタ関係をたどって「使われているかどうか」をチェックするため、メモリ上をあちこち行き来するアクセスが多くなります。
Step by Stepで検索していくイメージです。(赤矢印を辿っていくイメージ)

GreenTeaではページ(Go では 8 KiB の span 単位) ごとにmarkを実行していきます。

  • まずルートから参照されるページを特定
  • ページごとに「その中のどのオブジェクトが参照されているか」を調べる
    という流れに変わりました。

以下の図のように、ルートからページ(下図での 1 レーン)ごとに探索していきます。
ルートからたどった後は黄色レーンへ進み、緑の矢印が mark していくイメージです。
最後に青レーンへと辿ることで、少ないスキャンで全体を mark しきることができます。

これにより work-list がページ単位になり、オブジェクト単位より大幅に少なくなります。
また、ページ内のオブジェクトには seen / scanned といった軽量なメタデータが用意され、効率的に探索が進む仕組みになっています。

新ロジックによるメリット

ページ単位で GC を進めることで、以下の複数のメリットが生まれます。

  • メモリの局所性が向上し CPU キャッシュが効きやすくなる
  • 巨大な work-list を扱わないため、GC ワーカー間のキュー競合が減る
  • 複数 CPU ソケットや多数コアを持つサーバでも効率が落ちにくい
  • DRAM アクセス待ち時間が大きく減る

結果として、mark フェーズのコストが大幅に下がり、全体の GC オーバーヘッド削減につながります。

まとめ

いかがでしたでしょうか。最新版のGCに興味が湧いてきたことと思います!

最後にポイントをまとめると

  • Go 1.25 では GOEXPERIMENT=greenteagc で利用できる
  • GC オーバーヘッドを 10〜最大 40% 削減 できる事例がある
  • Go 1.26 でデフォルト採用が予定されている
  • 特に 大量の小さなオブジェクトを扱うサービス で恩恵が大きい

下記ブログ記事ではそれぞれのロジックの詳細をStep by Stepで説明してくださっているので、とてもわかりやすいです。
より詳しく知りたい方はぜひご覧ください。
https://go.dev/blog/greenteagc

最後に

AI Shiftではエンジニアの採用に力を入れています!
少しでも興味を持っていただけましたら、カジュアル面談でお話しませんか?
(オンライン・19時以降の面談も可能です!)
【面談フォームはこちら】
https://hrmos.co/pages/cyberagent-group/jobs/1826557091831955459

参考

AI Shift Tech Blog

Discussion