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.2k
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
GC25 Recap+: Advancing Go Garbage Collection with Green Tea
2025/9/30 Go 1.25 リリースパーティ & GopherCon 2025 報告会にて登壇した際の資料です。
Takuto Nagami
September 30, 2025
More Decks by Takuto Nagami
See All by Takuto Nagami
GopherCon @シアトル に行ってきました
logica0419
0
320
型落ちシンクライアント端末のPoEモジュールを自作したかった話
logica0419
0
490
The Journey of Connecting Japan to the Global Go Community
logica0419
1
89
Discovering Cilium: What eBPF Enabled in K8s Networking
logica0419
0
110
Do Gophers Dream of Stack Overflow?
logica0419
0
54
今こそ学びたいKubernetesネットワーク ~CNIが繋ぐNWとプラットフォームの「フラッと」な対話
logica0419
10
1.4k
キャリア科目では教えてくれない、就活を生き抜く法則
logica0419
2
320
歴史から学ぶ、Goのメモリ管理基礎
logica0419
17
4.3k
【2025改訂版】ITエンジニアとして知っておいてほしい、電子メールという大きな穴
logica0419
2
330
Other Decks in Technology
See All in Technology
AI駆動開発はどこまで来たのか? ファインディの最新実態調査で読み解く現在地 Devin Con Tokyo
akiratom
4
1.8k
1.5時間を無駄にして学んだwsl2におけるaptとsnapの選択と仕組み
yosaka0123
0
460
全社に広がるMCPサーバーを、 どう安全に管理するか MCPass開発の舞台裏
mtpooh
3
170
tamachi.goを支える技術
rymiyamoto
0
110
markdown-poster Introduction
kazamori
0
380
『自分で判断できるか』を基準に、プロダクトのハンズオン研修でAI利用の線を引いてみた / Where We Drew the Line on AI in Hands-on Training
honyanya
0
390
The Django UUID Story - DjangoCon US 2026
pauloxnet
0
300
最新技術に積極チャレンジ!EKS共通基盤のこれまでとこれから
daitak
0
240
AIレビュー時代に必要なのは、SLOで引く撤退ライン
nobuoooo
0
150
AWSとGitHub Actionsの責任境界と 組織で安全に使用する取り組み
nealle
0
200
Bill One 開発エンジニア 紹介資料
sansan33
PRO
7
20k
どんな手を使っても絶対間に合わせるスケジューラ
asari194617
0
1.5k
Featured
See All Featured
Agile that works and the tools we love
rasmusluckow
331
22k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.1k
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
260
The Illustrated Children's Guide to Kubernetes
chrisshort
51
53k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.3k
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
SEO for Brand Visibility & Recognition
aleyda
0
4.7k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
Un-Boring Meetings
codingconduct
0
400
How GitHub (no longer) Works
holman
316
150k
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
2
3.8k
Scaling GitHub
holman
464
140k
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、試してみてね!