🎃

[Go1.26]Goroutine leak profileを試してみた

に公開

Goroutine leak profileとは

Go1.26で実験的に導入される機能

runtime/pprofにgoroutineleakと言うプロファイル形式が入りました。

buildや実行のタイミングでGOEXPERIMENT=goroutineleakprofileとすると有効化できる。

また有効化することで、net/http/pprofからも参照できるようになるとのこと。

https://go.dev/doc/go1.26#goroutineleak-profiles

まずはリークするコードを書いてみましょう

package main

import (
	"log"
	"net/http"
	_ "net/http/pprof"
)

func leakWorker(ch chan int) {
	ch <- 1
}

func main() {
	ch := make(chan int)
	go leakWorker(ch)

	log.Println("pprof listen on :6060")
	log.Fatal(http.ListenAndServe("localhost:6060", nil))
}

このコードはch <- 1が受信がないことでleakが起きる実装です。

build後、go toolを実行し状況を確認

▶ go tool pprof http://localhost:6060/debug/pprof/goroutineleak
Fetching profile over HTTP from http://localhost:6060/debug/pprof/goroutineleak
Saved profile in /pprof/pprof.leak-test.goroutineleak.006.pb.gz
File: leak-test
Type: goroutineleak
Time: 2026-01-03 18:21:45 JST
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) top
Showing nodes accounting for 1, 100% of 1 total
      flat  flat%   sum%        cum   cum%
         1   100%   100%          1   100%  runtime.gopark
         0     0%   100%          1   100%  main.leakWorker
         0     0%   100%          1   100%  runtime.chansend
         0     0%   100%          1   100%  runtime.chansend1
(pprof) list leakWorker
Total: 1
ROUTINE ======================== main.leakWorker in ~/sandbox/sample-goroutine-leak/main.go
         0          1 (flat, cum)   100% of Total
         .          .      9:func leakWorker(ch chan int) {
         .          1     10:   ch <- 1
         .          .     11:}
         .          .     12:
         .          .     13:func main() {
         .          .     14:   ch := make(chan int)
         .          .     15:   go leakWorker(ch)
(pprof)

今の状態だとリークしていることがわかります。

list leakWorkerでより詳細にリークしているがつかめます。

ではleak、リークを修正しましょう。

func main() {
  ---

  <-ch // 受け取れるように追加
}

今は受信先がいないので起きているので、<-chと追加するだけでリークが解消されると思います。

▶ go tool pprof http://localhost:6060/debug/pprof/goroutineleak
Fetching profile over HTTP from http://localhost:6060/debug/pprof/goroutineleak
Saved profile in /pprof/pprof.leak-test.goroutineleak.005.pb.gz
File: leak-test
Type: goroutineleak
Time: 2026-01-04 10:25:04 JST
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) top
Showing nodes accounting for 0, 0% of 0 total
      flat  flat%   sum%        cum   cum%

確認するとリークが解消されました。

Discussion