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
Go 1.26 リリースパーティ
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
sivchari
February 26, 2026
0
120
Go 1.26 リリースパーティ
sivchari
February 26, 2026
Tweet
Share
More Decks by sivchari
See All by sivchari
govalid ~ Type-safe validation tool ~
sivchari
0
65
Go1.25 リリースパーティ ~ nil pointer bug ~
sivchari
0
66
Google Developer Group - DevFest Tokyo 2025
sivchari
0
66
Who tests the Tests ?
sivchari
0
66
静的解析 x Kubernetes API Conventions = Kube API Linter ~ ベストプラクティスに準拠したカスタムリソースの作り方と運用 ~
sivchari
0
130
What's GOCACHEPROG ?
sivchari
1
490
gh_extensionsによる快適なOSS生活.pdf
sivchari
0
96
Visualization Go scheduler by gosched-simulator
sivchari
1
560
protoc pluginのはじめかた
sivchari
0
99
Featured
See All Featured
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
230
Believing is Seeing
oripsolob
1
86
YesSQL, Process and Tooling at Scale
rocio
174
15k
Marketing to machines
jonoalderson
1
5k
Product Roadmaps are Hard
iamctodd
PRO
55
12k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
61k
Rebuilding a faster, lazier Slack
samanthasiow
85
9.4k
Discover your Explorer Soul
emna__ayadi
2
1.1k
How to Think Like a Performance Engineer
csswizardry
28
2.5k
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
2
180
Building Adaptive Systems
keathley
44
3k
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
320
Transcript
Go 1.26 リリースパーティ goroutine leak profileについて The Go gopher was
designed by Renee French
もくじ • goroutine leak profileとは • goroutine leakの検出方法 • goroutine
leakを検出できないケース • まとめ
自己紹介 渋谷拓真 Go Conference メインオーガナイザー OSS ◦ Kubernetes メンテナー ◦
Argo CD メンテナー Kubernetes 2025 Contributor Award 3Dプリンターにハマってます
goroutine leak profileとは
goroutine leak profileとは Go 1.26で追加された新しい pprof profile • CL#688335 •
ブロックされており復帰不可能な goroutineを検出する • GCの到達可能性を利用する • 1.26ではGOEXPERIMENTで、1.27からはデフォルトになる予定
goroutine leak profileとは GOEXPERIMENT=goroutineleakprofile go build -o myapp • net/http/pprof
• runtime/pprof goroutine 123 [chan send] (leaked): main.leaky.func1() /path/to/main.go:25 +0x1c created by main.leaky in goroutine 1 /path/to/main.go:24 +0x2c
goroutine leakの検出方法
goroutine leak profileの検出方法 内部でgoroutineleak profileがリクエストされた時にトリガーされる net/httpでもruntime/pprofでも(&Profile).WriteToが呼ばれる var goroutineLeakProfile = &Profile{
name: "goroutineleak", count: runtime_goroutineleakcount, write: writeGoroutineLeak, }
writeGoroutineLeak リーク検出用の GCをトリガーする関数を呼ぶ runtime_goroutineLeakGC() //golinkename runtime_goroutineLeakGC runtime.goroutineLeakGC func runtime_goroutineLeakGC()
runtime_goroutineLeakGC goroutineLeakを確認するチェックをつける func goroutineLeakGC() { work.goroutineLeak.pending.Store(true) for work.goroutineLeak.pending.Load() { GC()
} }
なぜGCに組み込むのか リーク検出は特定の goroutineを操作できない状態 • GCは到達不可能なオブジェクトを削除する • GCのマークを活用することで到達可能性を検出できる
しかしそのまま使いまわせない Goは内部でallgsという変数から全ての goroutineに到達できてしまう • waiting(*sudog)を使用してブロッキングかどうかは確認できてしまう • ブロッキングでも参照できてしまいリークかどうかわからなくなる allgs → blocking
g → sudog → c → blocking channel
maybeTraceablePtrの導入 リーク検出時の GCでは追跡を行わないようにポインタを nilにする • nilのため以降の GCで追跡対象に含めないようにする • リーク検出後にマークして追跡対象に戻すため回収されてしまうリスクは 回避している
gcPrepareMarkToots goroutine leakを検出する場合はソートして先頭実行可能・末尾ブロック中 に並べ替える if work.goroutineLeak.enabled { work.stackRoots, work.nMaybeRunnableStackRoots =
allGsSnapshotSortedForGC() } else { work.stackRoots = allGsSnapshot() work.nMaybeRunnableStackRoots = len(work.stackRoots) }
findGoroutineLeaks マーク完了後に Eventually Runnableでなければリークとみなす if findMaybeRunnableGoroutines() { return false }
for i := work.nMaybeRunnableStackRoots; i < work.nStackRoots; i++ { gp := work.stackRoots[i] casgstatus(gp, _Gwaiting, _Gleaked) shadePrimitivesOnLeak(gp) }
Eventually Runnableとは 実行可能な sudogのchannelがマークされている • 実行可能な goroutineがアクセスできる • リークを疑われていたがリークではないと考える
Eventually Runnableとは 実行可能な sudogのchannelがマークされている • 実行可能な goroutineがアクセスできる • リークを疑われていたがリークではないと考える
findGoroutineLeaks sharedPrimitivesOnLeakでリーク対象もマーキングして回収防止 if findMaybeRunnableGoroutines() { return false } for i
:= work.nMaybeRunnableStackRoots; i < work.nStackRoots; i++ { gp := work.stackRoots[i] casgstatus(gp, _Gwaiting, _Gleaked) shadePrimitivesOnLeak(gp) }
goroutine leakを検出できないケース
一部ケースは検出できない 銀の弾丸ではない • グローバル変数に定義されている • グローバルはマークされてしまう ◦ Eventually Runnableと判定 var
ch = make(chan int) func leaky() { go func() { ch <- 42 }() }
一部ケースは検出できない 銀の弾丸ではない • ローカル変数で使用されている • fがforで実行されて runnable ◦ Eventually Runnableと判定
• forのなかでchのselectがあったら ◦ waitingとなり検出される func leaky() { ch := make(chan int) go f(ch) go func() { ch <- 42 }() } func f(ch chan int) { for {} }
まとめ
まとめ • Go1.26からgoroutine leakを検出できるようになった • GCの持つ到達可能性の追跡を活用している • uberのgoleakと併用して lekaを防止しよう!
ありがとうございました!
おしらせ