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
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Takuto Nagami
September 30, 2025
Technology
3
930
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
キャリア科目では教えてくれない、就活を生き抜く法則
logica0419
1
180
歴史から学ぶ、Goのメモリ管理基礎
logica0419
14
3.1k
【2025改訂版】ITエンジニアとして知っておいてほしい、電子メールという大きな穴
logica0419
2
140
Fundamentals of Memory Management in Go: Learning Through the History
logica0419
1
130
GopherCon Tourのつくりかた
logica0419
2
96
Go言語はstack overflowの夢を見るか?
logica0419
2
770
あなたの言葉に力を与える、演繹的なアプローチ
logica0419
1
260
GopherCon Tour 概略
logica0419
2
530
言葉の壁を越えて ~Gophers EXと歩む海外登壇への道~
logica0419
1
75
Other Decks in Technology
See All in Technology
生成AI時代にこそ求められるSRE / SRE for Gen AI era
ymotongpoo
2
100
一番人に近いコードレビューア CodeRabbit
kinopeee
0
120
CodeRabbit CLI + Claude Codeの連携について
oikon48
1
690
漸進的過負荷の原則
sansantech
PRO
3
420
【NGK2026S】日本株のシステムトレードに入門してみた
kazuhitotakahashi
0
220
The Engineer with a Three-Year Cycle - 2
e99h2121
0
200
MySQLのJSON機能の活用術
ikomachi226
0
110
Claude Codeベストプラクティスまとめ
minorun365
53
30k
Vitest Highlights in Angular
rainerhahnekamp
0
120
re:Inventで出たインフラエンジニアが嬉しかったアップデート
nagisa53
4
220
2026年はチャンキングを極める!
shibuiwilliam
8
1.6k
Amazon ElastiCacheのコスト最適化を考える/Elasticache Cost Optimization
quiver
0
290
Featured
See All Featured
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
110
Faster Mobile Websites
deanohume
310
31k
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
48
The Invisible Side of Design
smashingmag
302
51k
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
100
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
0
1.1k
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
310
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
55
3.2k
Technical Leadership for Architectural Decision Making
baasie
1
220
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.6k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
5.8k
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
2
390
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、試してみてね!