Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Green Tea GCを見てみる

Avatar for is1 is1
September 25, 2025
210

Green Tea GCを見てみる

dmm.go #11で発表した資料です。

Avatar for is1

is1

September 25, 2025

Transcript

  1. © DMM © DMM CONFIDENTIAL Green Tea GCを見てみる dmm.go #11

    合同会社EXNOA プラットフォーム技術開発本部 伊藤 晋梧 2025/09/17
  2. © DMM おしながき • Goのメモリ管理とGCの課題 • メモリ確保 • メモリ解放 •

    Green Tea Garbage Collectionのアプローチ • パフォーマンスについて • まとめ 4
  3. © DMM おしながき • Goのメモリ管理とGCの課題 • メモリ確保 • メモリ解放 •

    Green Tea Garbage Collectionのアプローチ • パフォーマンスについて • まとめ 6
  4. © DMM メモリ確保について 9 func (h *mheap) alloc(npages uintptr, spanclass

    spanClass) *mspan { var s *mspan systemstack(func() { if !isSweepDone() { h.reclaim(npages) } s = h.allocSpan(npages, spanAllocHeap, spanclass) }) return s } https://github.com/golang/go/blob/6a08e80399bd65b95e60e3c74b7e1f86754752a7/src/runtime/mheap.go#L1008
  5. © DMM メモリ確保について 10 func (h *mheap) alloc(npages uintptr, spanclass

    spanClass) *mspan { var s *mspan systemstack(func() { if !isSweepDone() { h.reclaim(npages) } s = h.allocSpan(npages, spanAllocHeap, spanclass) }) return s } https://github.com/golang/go/blob/6a08e80399bd65b95e60e3c74b7e1f86754752a7/src/runtime/mheap.go#L1008 メモリの確保処理と 実行中のプログラム の競合を回避
  6. © DMM メモリ確保について 11 func (h *mheap) alloc(npages uintptr, spanclass

    spanClass) *mspan { var s *mspan systemstack(func() { if !isSweepDone() { h.reclaim(npages) } s = h.allocSpan(npages, spanAllocHeap, spanclass) }) return s } https://github.com/golang/go/blob/6a08e80399bd65b95e60e3c74b7e1f86754752a7/src/runtime/mheap.go#L1008 メモリ確保処理 (以前解放した  メ モリ領域か、OSから 確保する)
  7. © DMM メモリ解放について • GoではGarbage Collection(GC)を導入 • Go 1.5からConcurrent GC

    + mark & sweepを採用 • プログラム動作中に並行で実行 • mark & sweep • markフェーズ • tri-color marking: オブジェクト*を色で分類 • sweepフェーズ • 未到達のオブジェクトを開放していく • Concurrent GC • Write Barrier • GC作業中のプログラムによるオブジェクトの書き換えに対応 • 12 * ヒープ領域に割り当てられたもの
  8. © DMM メモリ解放について • GoではGarbage Collection(GC)を導入 • Go 1.5からConcurrent GC

    + mark & sweepを採用 • プログラム動作中に並行で実行 • mark & sweep • markフェーズ • tri-color marking: オブジェクト *を色で分類 • sweepフェーズ • 未到達のオブジェクトを開放していく • Concurrent GC • Write Barrier • GC作業中のプログラムによるオブジェクトの書き換えに対応 • 13 * ヒープ領域に割り当てられたもの
  9. © DMM tri-color marking(3色マーキング) オブジェクトを3色で分類 • 白 • 未到達 •

    灰 • 到達済 • そのオブジェクトが参照しているオブジェクトは未スキャン • 黒 • 到達済 • 参照しているオブジェクトもすべてスキャン済 14
  10. © DMM mark & sweep • GC(ワーカー) • マークフェーズで動作する複数のgoroutine •

    オブジェクト単位でスキャン • スキャン = そのオブジェクトが参照しているオブジェクトを発見する • ワークキュー • 到達可能になったオブジェクト = GCワーカーが作業(スキャン)予定の  オブ ジェクトが入るキュー • キューが空になるとmark終了 15
  11. © DMM これまでのGCの課題 • メモリの局所性を生かすことができていない • 時間的局所性: 一度参照したメモリ領域は再び参照される可能性が高い • ワークキューに入れるため、処理のタイミングがズレる

    • キャッシュミスの発生によるCPU負荷 • 空間的局所性: 参照されたデータの近傍も参照される可能性が高い • オブジェクト単位で見ていくため、メモリ内全域を走査する 24 あまり効率的でない
  12. © DMM おしながき • Goのメモリ管理とGCの課題 • メモリ確保 • メモリ解放 •

    Green Tea Garbage Collectionのアプローチ • パフォーマンスについて • まとめ 25
  13. © DMM Green Tea GC🍵 Go 1.25.0から試験的に導入された改良版GC • メモリの局所性を改善 →

    CPU負荷の軽減、パフォーマンス改善 • 従来のmark & sweepと大きな変更はない • 白、灰、黒の3色で分類 • スパンという小さなメモリのブロック単位でスキャンする • スパンごとのマークビットとスキャンビットを利用 • マークビットがセットされている場合、スパン内を走査 • 走査完了後、スキャンビットをセットする 26
  14. © DMM Green Tea GCの流れ: mark 27 ヒープ Span 1

    Span 2 Span 3 Span 4 スパンキュー Span 1 スキャン開 始位置 未到達 未スキャン スキャン済
  15. © DMM Green Tea GCの流れ: mark 28 ヒープ Span 1

    Span 2 Span 3 Span 4 スパンキュー Span 1 未到達 未スキャン スキャン済
  16. © DMM Green Tea GCの流れ: mark 29 ヒープ Span 1

    Span 2 Span 3 Span 4 スパンキュー Span 2 Span 3 未到達 未スキャン スキャン済
  17. © DMM Green Tea GCの流れ: mark 30 ヒープ Span 1

    Span 2 Span 3 Span 4 スパンキュー Span 3 Span 4 未到達 未スキャン スキャン済
  18. © DMM Green Tea GCの流れ: mark 31 ヒープ Span 1

    Span 2 Span 3 Span 4 スパンキュー Span 2 未到達 未スキャン スキャン済
  19. © DMM Green Tea GCの流れ: mark 32 ヒープ Span 1

    Span 2 Span 3 Span 4 スパンキュー 未到達 未スキャン スキャン済
  20. © DMM Green Tea GCの流れ: sweep 33 ヒープ Span 1

    Span 2 Span 3 Span 4 白のままの未到達 オブジェクトを解放 未到達 未スキャン スキャン済
  21. © DMM おしながき • Goのメモリ管理とGCの課題 • メモリ確保 • メモリ解放 •

    Green Tea Garbage Collectionのアプローチ • パフォーマンスについて • まとめ 34
  22. © DMM パフォーマンスについて • 現状パフォーマンスは測定中のため、issueに記載されている計測 結果 の一部を紹介 • 手元でGreen Tea GCを動作させるには

    でビルドすることでできる 35 参考: https://github.com/golang/go/issues/73581#issuecomment-2847696497 $ go version go version go1.25.0 darwin/arm64 $ GOEXPERIMENT=greenteagc go build main.go
  23. © DMM パフォーマンス測定結果(2/3) 実際のサービスでもパフォーマンス改善が報告されている • HydrAIDE • オープンソースのデータエンジン • pub/sub等をサポート

    • メモリ上でデータを保持 • 結果 • CPU時間が22%減少 • ヒープの大きさが8%減少 37 参考 https://dev.to/hydraide/go-125-greentea-gc-vs-classic-hydraide-1m-swamp-test-shows-22-cpu-efficiency-8-memory-294h https://github.com/golang/go/issues/73581#issuecomment-3241368478
  24. © DMM おしながき • Goのメモリ管理とGCの課題 • メモリ確保 • メモリ解放 •

    Green Tea Garbage Collectionのアプローチ • パフォーマンスについて • まとめ 38
  25. © DMM まとめ • 現状のGCではメモリの局所性を活かせず効率があまり良くない • Green Tea GCによって局所性を活かしたGCができるようになる •

    CPUにかかる負荷の軽減やヒープメモリの増加量軽減など、   パ フォーマンスの向上も確認されている • Green Tea GCはあくまでも現状のGCの改善版 39