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
3
980
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
今こそ学びたいKubernetesネットワーク ~CNIが繋ぐNWとプラットフォームの「フラッと」な対話
logica0419
9
790
キャリア科目では教えてくれない、就活を生き抜く法則
logica0419
2
250
歴史から学ぶ、Goのメモリ管理基礎
logica0419
17
3.4k
【2025改訂版】ITエンジニアとして知っておいてほしい、電子メールという大きな穴
logica0419
2
160
Fundamentals of Memory Management in Go: Learning Through the History
logica0419
1
140
GopherCon Tourのつくりかた
logica0419
2
110
Go言語はstack overflowの夢を見るか?
logica0419
2
810
あなたの言葉に力を与える、演繹的なアプローチ
logica0419
1
280
GopherCon Tour 概略
logica0419
2
560
Other Decks in Technology
See All in Technology
なぜAIは チーム開発を 速くしないのか
tan_go238
8
3.3k
Claude Codeと駆け抜ける 情報収集と実践録
sontixyou
1
250
社内ワークショップで終わらせない 業務改善AIエージェント開発
lycorptech_jp
PRO
1
220
1 年間の育休から時短勤務で復帰した私が、 AI を駆使して立ち上がりを早めた話
lycorptech_jp
PRO
0
100
大規模な組織におけるAI Agent活用の促進と課題
lycorptech_jp
PRO
1
1k
ブログの作成に音声AIツールを使って音声入力しようとした話
smt7174
1
150
Agent Ready になるためにデータ基盤チームが今年やること / How We're Making Our Data Platform Agent-Ready
zaimy
0
150
AITuberKit+Bedrock AgentCoreで作る 3Dキャラクターエージェント
yokomachi
2
1.5k
自律型コーディングエージェントでどこまで出来るかやってみる~ Claude Code vs GitHub Copilot(Agent mode) ~ / How Far Can Autonomous Coding Agents Go? ~Claude Code vs GitHub Copilot (Agent Mode)~
jnymyk
0
190
バイブコーディングで作ったものを紹介
tatsuya1970
0
160
三菱UFJ銀行におけるエンタープライズAI駆動開発のリアル / Enterprise AI_Driven Development at MUFG Bank: The Real Story
muit
4
6.2k
vol11_ねこIoTLT_お遊びVibeCoding
1027kg
0
160
Featured
See All Featured
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.4k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
760
The Spectacular Lies of Maps
axbom
PRO
1
560
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
WCS-LA-2024
lcolladotor
0
470
Optimising Largest Contentful Paint
csswizardry
37
3.6k
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
270
エンジニアに許された特別な時間の終わり
watany
106
230k
Testing 201, or: Great Expectations
jmmastey
46
8.1k
Code Reviewing Like a Champion
maltzj
527
40k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
620
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、試してみてね!