Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
GC25 Recap+: Advancing Go Garbage Collection wi...
Search
Takuto Nagami
September 30, 2025
Technology
1
690
GC25 Recap+: Advancing Go Garbage Collection with Green Tea
2025/9/30 Go 1.25 リリースパーティ & GopherCon 2025 報告会にて登壇した際の資料です。
Takuto Nagami
September 30, 2025
Tweet
Share
More Decks by Takuto Nagami
See All by Takuto Nagami
Fundamentals of Memory Management in Go: Learning Through the History
logica0419
0
77
GopherCon Tourのつくりかた
logica0419
1
63
Go言語はstack overflowの夢を見るか?
logica0419
1
690
あなたの言葉に力を与える、演繹的なアプローチ
logica0419
1
220
GopherCon Tour 概略
logica0419
2
400
言葉の壁を越えて ~Gophers EXと歩む海外登壇への道~
logica0419
1
58
Maintainer Meetupで「生の声」を聞く ~講演だけじゃないKubeCon
logica0419
1
590
理想の英語力に一直線!最高効率な英語学習のすゝめ
logica0419
6
450
Gophers EX: What We’ve Been Up To in Feb–May 2025 / 2025年2~5月 Gophers EX活動報告書
logica0419
0
89
Other Decks in Technology
See All in Technology
AIがコードを書いてくれるなら、新米エンジニアは何をする? / komekaigi2025
nkzn
25
18k
MCP サーバーの基礎から実践レベルの知識まで
azukiazusa1
25
13k
Playwrightで始めるUI自動テスト入門
devops_vtj
0
230
Spec Driven Development入門/spec_driven_development_for_learners
hanhan1978
1
970
AIとの協業で実現!レガシーコードをKotlinらしく生まれ変わらせる実践ガイド
zozotech
PRO
2
370
隙間ツール開発のすすめ / PHP Conference Fukuoka 2025
meihei3
0
200
内部品質・フロー効率・コミュニケーションコストを悪化させ現場を苦しめかねない16の組織設計アンチパターン[超簡易版] / 16 Organization Design Anti-Patterns for Software Development
mtx2s
2
120
Master Dataグループ紹介資料
sansan33
PRO
1
3.9k
なぜ新機能リリース翌日にモニタリング可能なのか? 〜リードタイム短縮とリソース問題を「自走」で改善した話〜 / data_summit_findy_Session_2
sansan_randd
1
140
技術の総合格闘技!?AIインフラの現在と未来。
ebiken
PRO
0
190
QAEが生成AIと越える、ソフトウェア開発の境界線
rinchsan
0
890
設計に疎いエンジニアでも始めやすいアーキテクチャドキュメント
phaya72
30
20k
Featured
See All Featured
Speed Design
sergeychernyshev
32
1.2k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
23
1.5k
The Power of CSS Pseudo Elements
geoffreycrofte
80
6k
jQuery: Nuts, Bolts and Bling
dougneiner
65
8k
Product Roadmaps are Hard
iamctodd
PRO
55
11k
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
116
20k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.1k
The Language of Interfaces
destraynor
162
25k
The Invisible Side of Design
smashingmag
302
51k
Transcript
Takuto Nagami @logica0419 Recap+: Advancing Go Garbage Collection with Green
Tea
今回Recapするのは… Advancing Go Garbage Collection with Green Tea by Michael
Knyszek
要約 (TL;DR): Go 1.26から ガベージコレクションが 速くなります。
本題に入る前に 前提知識をおさらい しておきましょう
スタック・ヒープと ガベージコレクション
アプリケーションから見たメモリ . . . • Key-value storeの形で表される ◦ Key: Memory
address ◦ Value: 各アドレス1バイト • ほとんどの高級言語は、変数を メモリに格納する時、スタック とヒープの2つの領域を(言語側 で作って)使い分ける 0x0000 0x0001 0x0002 0x0003
. . . スタック
. . . main() stack frame スタック
. . . main() stack frame 5 スタック {v addr}
. . . main() stack frame 5 a() stack frame
スタック {v addr}
. . . main() stack frame 5 a() stack frame
5 スタック {arg addr} {v addr}
. . . main() stack frame 5 a() stack frame
5 7 スタック {arg addr} {a addr} {v addr}
. . スタック main() stack frame 5 a() stack frame
{arg addr} {a addr} {v addr} 5 7 b() stack frame
. . スタック main() stack frame 5 a() stack frame
{arg addr} {arg addr} {a addr} {v addr} 5 7 b() stack frame 7
. . スタック main() stack frame 5 a() stack frame
{arg addr} {b addr} {arg addr} {a addr} {v addr} 5 7 b() stack frame 7 1
. . . スタック main() stack frame 5 a() stack
frame {arg addr} {a addr} {v addr} 5 7
. . . スタック main() stack frame 5 {v addr}
. . . スタック プログラム終了
スタックが苦手なデータ • 大きなデータ ◦ Stack Overflowを誘発する • コンパイル時にサイズが決まらないデータ ◦ slice・mapなど
◦ スタックはコンパイル時に全て定義される ▪ 動的にサイズを変えるのは効率が悪い • 複数の関数でまたがって使うデータ ◦ グローバル変数など
ヒープ . . . . . . . main() stack
frame
ヒープ . . . . . . . [] {slice_h
addr} main() stack frame
. . . . . . . [] {slice_h addr}
{slice addr} main() stack frame ヒープ {slice_h addr}
ヒープ内でのオブジェクト管理 • 色んなデータ(オブジェクト)がヒープに入る ◦ バラバラに入れていたら管理が面倒 int (8 byte) struct (可変サイズ)
ポインタ (8 byte)
… … ヒープ内でのオブジェクト管理 • 同サイズのオブジェクトをスパンでまとめる int (8 byte) struct (8
byte) struct struct (32 byte) struct struct int int スパン1 (8 byte用) スパン2 (8 byte用) スパン3 (32 byte用) int int
ヒープ内でのオブジェクト管理 • スパン(mspan)はもっと大きな単位でまとめられる ◦ mcentral ▪ 同じサイズのスパンをグループ化 ◦ arena ▪
mheapが1回で引き出してくるメモリ量 ▪ mcentralを複数格納 ◦ mheap ▪ ヒープ本体
ガベージコレクション(GC) • Cなどでは、ヒープに置いたデータを使わなくなった時 プログラマーが明示的に削除 ◦ 削除忘れによってメモリ使用量が無限に増える memory leakが多発 ↓ •
要らなくなったヒープ内のデータを自動的に削除する 機能がガベージコレクション
これまでのGCと その挙動
GoのGC • Mark and Sweepアルゴリズム ◦ Mark phase: まだ使われているオブジェクトを確認 ◦
Sweep phase: マークされていない物を削除 • Tri-color markingを使うことで中断可能に ◦ 詳しいことは今回割愛 • 色々頑張ってアプリケーションと並列で実行 ◦ 今回割愛
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T ここから、Tri-color markingの root scan phase
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T ここから、Tri-color markingの mark phase
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T ここから sweep phase
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T [4]*T [4]*T
メモリ局所性と OSのメモリ読み込み戦略
メモリ局所性(参照の局所性)とは • データアクセスの傾向に関する概念 • 時間的局所性 ◦ 同じデータには近いうちに再度アクセスされやすい • 空間的局所性 ◦
近い場所にあるデータは一緒にアクセスされやすい • ↑ のような傾向が強いと「局所性が高い」 • 世の中のタスクのほとんどは局所性が高いので、OSは それに合わせて最適化している
OSのメモリ読み込み戦略 • 多段キャッシュをする ◦ CPUの処理部に近づくほど、小さく速い • この構造を活かすための読み込み戦略が… CPU内 キャッシュ (多段)
メモリ (DRAM) ストレージ 小さくて速い 大きくて遅い
OSのメモリ読み込み戦略 • ページングを行う メモリ ページ1 (4 kB) ページ2 (4 kB)
ページ3 (4 kB) CPU キャッシュ CPU 処理部
OSのメモリ読み込み戦略 • ページングを行う メモリ ページ1 (4 kB) ページ2 (4 kB)
ページ3 (4 kB) CPU キャッシュ CPU 処理部 ページ1内 データ欲しい
OSのメモリ読み込み戦略 • ページングを行う メモリ ページ1 (4 kB) ページ2 (4 kB)
ページ3 (4 kB) CPU キャッシュ CPU 処理部 ページ1内 データ欲しい
OSのメモリ読み込み戦略 • ページングを行う メモリ ページ1 (4 kB) ページ2 (4 kB)
ページ3 (4 kB) CPU キャッシュ CPU 処理部 ページ1内 データ欲しい
OSのメモリ読み込み戦略 • ページングを行う メモリ ページ1 (4 kB) ページ2 (4 kB)
ページ3 (4 kB) CPU キャッシュ CPU 処理部 ページ1内 データ欲しい ページ1 (4 kB)
OSのメモリ読み込み戦略 • ページングを行う メモリ ページ1 (4 kB) ページ2 (4 kB)
ページ3 (4 kB) CPU キャッシュ CPU 処理部 データを 使って処理 ページ1 (4 kB)
OSのメモリ読み込み戦略 • ページングを行う メモリ ページ1 (4 kB) ページ2 (4 kB)
ページ3 (4 kB) CPU キャッシュ CPU 処理部 次(ページ1)の データ欲しい ページ1 (4 kB)
OSのメモリ読み込み戦略 • ページングを行う メモリ ページ1 (4 kB) ページ2 (4 kB)
ページ3 (4 kB) CPU キャッシュ CPU 処理部 次(ページ1)の データ欲しい ページ1 (4 kB)
OSのメモリ読み込み戦略 • ページングを行う メモリ ページ1 (4 kB) ページ2 (4 kB)
ページ3 (4 kB) CPU キャッシュ CPU 処理部 次データを 使って処理 ページ1 (4 kB)
キャッシュ戦略は 時間・空間的局所性が高い タスクに効率化されている キャッシュは局所性の高さに対処するという表現が自然
OSのメモリ読み込み戦略 • 近くのページをまとめて取ることも (更なる空間的 局所性対策) メモリ ページ1 (4 kB) ページ2
(4 kB) ページ3 (4 kB) CPU キャッシュ CPU 処理部 ページ1内 データ欲しい
OSのメモリ読み込み戦略 メモリ ページ1 (4 kB) ページ2 (4 kB) ページ3 (4
kB) CPU キャッシュ CPU 処理部 ページ1内 データ欲しい • 近くのページをまとめて取ることも (更なる空間的 局所性対策)
OSのメモリ読み込み戦略 メモリ ページ1 (4 kB) ページ2 (4 kB) ページ3 (4
kB) CPU キャッシュ CPU 処理部 ページ1内 データ欲しい • 近くのページをまとめて取ることも (更なる空間的 局所性対策)
OSのメモリ読み込み戦略 メモリ ページ1 (4 kB) ページ2 (4 kB) ページ3 (4
kB) CPU キャッシュ CPU 処理部 ページ1内 データ欲しい ページ1 (4 kB) ページ2 (4 kB) • 近くのページをまとめて取ることも (更なる空間的 局所性対策)
OSのメモリ読み込み戦略 メモリ ページ1 (4 kB) ページ2 (4 kB) ページ3 (4
kB) CPU キャッシュ CPU 処理部 データを 使って処理 ページ1 (4 kB) ページ2 (4 kB) • 近くのページをまとめて取ることも (更なる空間的 局所性対策)
OSのメモリ読み込み戦略 メモリ ページ1 (4 kB) ページ2 (4 kB) ページ3 (4
kB) CPU キャッシュ CPU 処理部 ページ2内 データ欲しい ページ1 (4 kB) ページ2 (4 kB) • 近くのページをまとめて取ることも (更なる空間的 局所性対策)
OSのメモリ読み込み戦略 メモリ ページ1 (4 kB) ページ2 (4 kB) ページ3 (4
kB) CPU キャッシュ CPU 処理部 ページ2内 データ欲しい ページ1 (4 kB) ページ2 (4 kB) • 近くのページをまとめて取ることも (更なる空間的 局所性対策)
OSのメモリ読み込み戦略 メモリ ページ1 (4 kB) ページ2 (4 kB) ページ3 (4
kB) CPU キャッシュ CPU 処理部 データを 使って処理 ページ1 (4 kB) ページ2 (4 kB) • 近くのページをまとめて取ることも (更なる空間的 局所性対策)
OSは様々な手法を用いて メモリ局所性の高いタスクを 効率的に走らせている これがGreen Teaへの伏線
Green Tea🍵とその挙動
… … おさらい: Goのヒープ管理 • 同サイズのオブジェクトをスパンでまとめる int (8 byte) struct
(8 byte) struct struct (32 byte) struct struct int int スパン1 (8 byte用) スパン2 (8 byte用) スパン3 (32 byte用) int int
スパンの実態 • Goのスパンは、OSのページを数個まとめたもの ◦ 原則となり合ったページが使われる • 同じスパンを読む方がOSのキャッシュ戦略を活かせる object スパン (32kB)
ページ (4 kB) ページ (4 kB) ページ (4 kB) object object object
これまでのGCの課題 • GC自体のメモリ局所性が低い ◦ スパン(ページ)間を飛び回っている ◦ OSのキャッシュ戦略を上手く活かせてない ▪ 遠いページに移動するたびキャッシュリセット •
↑ のせいでメモリ読み込みが遅く、CPUの処理性能を フルで活かせない ◦ CPUの進歩の方が速く、昔とは犠牲にしたいものが 逆になってしまった
Green Tea🍵 • メモリ局所性の高い、新たなマークアルゴリズム ◦ Tri-colorを拡張し、スパンごとにオブジェクトを スキャンする • 実は名前の由来が日本 ◦
Green Teaのプロトタイプを作ったのは、今のTech LeadであるAustine Clements ◦ プロトタイピングの大部分は、Austineさんが横浜 のカフェで大量の抹茶をしばきながら行った
Green Teaはスパンごとの オブジェクトスキャンで 局所性を上げている 実際の挙動を見てみましょう
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T おさらい: ここから sweep phase
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T T [4]*T [4]*T [4]*T
スタック var x *T var y *T 状態一覧 見てない 見る予定
今見てる もう見た スパンA スパンB スパンC スパンD T T T T T [4]*T [4]*T
実験: Green Teaって ホントに速いの?
効きそうなパターンを作成してみた
やってること 100万件の slice s □□□...
やってること s □□□... T a:□ b:□
やってること s □□□... T a:□ b:□ int □
やってること s □□□... T a:□ b:□ int □ まだsは 使う状態で
GC
T T T T []*T スタック var s *[]T スパン
(T 用) スパン (int 用) スパン ([]*T 用) T T.b T.b T.b T.b T.b T.b T.b
T T T T []*T スタック var s *[]T スパン
(T 用) スパン (int 用) スパン ([]*T 用) T T.b T.b T.b T.b T.b T.b T.b これまでなら
T T T T []*T スタック var s *[]T スパン
(T 用) スパン (int 用) スパン ([]*T 用) T T.b T.b T.b T.b T.b T.b T.b
T T T T []*T スタック var s *[]T スパン
(T 用) スパン (int 用) スパン ([]*T 用) T T.b T.b T.b T.b T.b T.b T.b
T T T T []*T スタック var s *[]T スパン
(T 用) スパン (int 用) スパン ([]*T 用) T T.b T.b T.b T.b T.b T.b T.b Green Teaなら
T T T T []*T スタック var s *[]T スパン
(T 用) スパン (int 用) スパン ([]*T 用) T T.b T.b T.b T.b T.b T.b T.b
T T T T []*T スタック var s *[]T スパン
(T 用) スパン (int 用) スパン ([]*T 用) T T.b T.b T.b T.b T.b T.b T.b
T T T T []*T スパン (T 用) スパン (int
用) スパン ([]*T 用) T T.b T.b T.b T.b T.b T.b T.b スタック var s *[]T こうなって欲しい (実際に確かめてはいません)
こんな感じで実行 (最適化は切った)
結果
結果 5回とも ちゃんと 速い
まとめ • Green Teaはスパン単位のスキャンで局所性をup • とてもシンプル、だけど一部のケースで強力 ◦ OSの特性をよく活かす方向性 Go 1.26から
ガベージコレクションが 速くなります。
ありがとう ございました Green Tea、試してみてね!