Slide 1

Slide 1 text

© DMM © DMM CONFIDENTIAL Green Tea GCを見てみる dmm.go #11 合同会社EXNOA プラットフォーム技術開発本部 伊藤 晋梧 2025/09/17

Slide 2

Slide 2 text

© DMM Go書いてますか?

Slide 3

Slide 3 text

© DMM Goのランタイム実装って見てますか?

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

© DMM スライドは 2025/9/3時点でのものです。 説明のために省略した点もあるため、正確な情報が欲しい方は https://github.com/golang/go/issues/73581 や実装を参照ください。

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

© DMM Goのメモリ管理 Goを書いている時はあまりメモリのことを意識しなくていい ⇒ ランタイムがよしなにやってくれている • メモリ確保 • メモリ解放 7

Slide 8

Slide 8 text

© DMM Goのメモリ管理 Goを書いている時はあまりメモリのことを意識しなくていい ⇒ ランタイムがよしなにやってくれている • メモリ確保 • メモリ解放 開発者は開発により集中できる 8

Slide 9

Slide 9 text

© 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

Slide 10

Slide 10 text

© 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 メモリの確保処理と 実行中のプログラム の競合を回避

Slide 11

Slide 11 text

© 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から 確保する)

Slide 12

Slide 12 text

© 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 * ヒープ領域に割り当てられたもの

Slide 13

Slide 13 text

© 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 * ヒープ領域に割り当てられたもの

Slide 14

Slide 14 text

© DMM tri-color marking(3色マーキング) オブジェクトを3色で分類 • 白 • 未到達 • 灰 • 到達済 • そのオブジェクトが参照しているオブジェクトは未スキャン • 黒 • 到達済 • 参照しているオブジェクトもすべてスキャン済 14

Slide 15

Slide 15 text

© DMM mark & sweep • GC(ワーカー) • マークフェーズで動作する複数のgoroutine • オブジェクト単位でスキャン • スキャン = そのオブジェクトが参照しているオブジェクトを発見する • ワークキュー • 到達可能になったオブジェクト = GCワーカーが作業(スキャン)予定の  オブ ジェクトが入るキュー • キューが空になるとmark終了 15

Slide 16

Slide 16 text

© DMM GCの流れ: mark 16 ヒープ 未到達 未スキャン スキャン済 オブジェクト ワーク キュー

Slide 17

Slide 17 text

© DMM GCの流れ: mark 17 ヒープ ワーク キュー スキャン開 始位置 未到達 未スキャン スキャン済

Slide 18

Slide 18 text

© DMM GCの流れ: mark 18 ヒープ ワーク キュー  を1つ消費、 2つエンキュー 未到達 未スキャン スキャン済

Slide 19

Slide 19 text

© DMM GCの流れ: mark 19 ヒープ ワーク キュー 未到達 未スキャン スキャン済

Slide 20

Slide 20 text

© DMM GCの流れ: mark 20 ヒープ ワーク キュー 未到達 未スキャン スキャン済

Slide 21

Slide 21 text

© DMM GCの流れ: mark 21 ヒープ ワーク キュー 未到達 未スキャン スキャン済

Slide 22

Slide 22 text

© DMM GCの流れ: mark 22 ヒープ ワーク キュー 未到達 未スキャン スキャン済

Slide 23

Slide 23 text

© DMM GCの流れ: sweep 23 白のままの未到達 オブジェクトを解放 ヒープ 未到達 未スキャン スキャン済

Slide 24

Slide 24 text

© DMM これまでのGCの課題 • メモリの局所性を生かすことができていない • 時間的局所性: 一度参照したメモリ領域は再び参照される可能性が高い • ワークキューに入れるため、処理のタイミングがズレる • キャッシュミスの発生によるCPU負荷 • 空間的局所性: 参照されたデータの近傍も参照される可能性が高い • オブジェクト単位で見ていくため、メモリ内全域を走査する 24 あまり効率的でない

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

© DMM Green Tea GC🍵 Go 1.25.0から試験的に導入された改良版GC • メモリの局所性を改善 → CPU負荷の軽減、パフォーマンス改善 • 従来のmark & sweepと大きな変更はない • 白、灰、黒の3色で分類 • スパンという小さなメモリのブロック単位でスキャンする • スパンごとのマークビットとスキャンビットを利用 • マークビットがセットされている場合、スパン内を走査 • 走査完了後、スキャンビットをセットする 26

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

© DMM Green Tea GCの流れ: sweep 33 ヒープ Span 1 Span 2 Span 3 Span 4 白のままの未到達 オブジェクトを解放 未到達 未スキャン スキャン済

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

© 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

Slide 36

Slide 36 text

© DMM パフォーマンス測定結果(1/3) 36 GCサイクルごとの CPU負荷が軽減した ヒープ領域の増加量が 緩やかになった https://github.com/golang/go/issues/73581#issuecomment-2884431096

Slide 37

Slide 37 text

© 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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

© DMM まとめ • 現状のGCではメモリの局所性を活かせず効率があまり良くない • Green Tea GCによって局所性を活かしたGCができるようになる • CPUにかかる負荷の軽減やヒープメモリの増加量軽減など、   パ フォーマンスの向上も確認されている • Green Tea GCはあくまでも現状のGCの改善版 39

Slide 40

Slide 40 text

© DMM ありがとうございました