KDOC 415: io.Readerのシグネチャはヒープエスケープを避ける設計になっている
この文書のステータス
- 作成
- 2025-07-01 貴島
- レビュー
- <署名>
概要
io.Reader, io.Writerのインターフェース設計には、ヒープのエスケープも関係しているという。
type Reader interface { Read(p []byte) (n int, err error) }
[]byte
の初期化は呼び出し側の責務になっている。これによって呼び出し側がメモリ管理できるようになる。スタックに留まり、スタックにエスケープするのを抑えられる。Readを何度呼んでも新しいヒープ確保が発生しない。
実際に試してみる。
tmpfile=$(mktemp /tmp/tmpgo.XXXXXX.go) cat > $tmpfile <<EOF package main func main() { // スタックに置いたまま buf := make([]byte, 2) Read2(buf) } // Read側で初期化して返すと、ヒープにエスケープしなければならない func Read1() []byte { return make([]byte, 1) } // 呼び出し側で初期化してもらうようにすると、ヒープにエスケープする必要がない func Read2([]byte) {} EOF go build -gcflags="-m" -o bin $tmpfile 2>&1 rm bin rm $tmpfile
# command-line-arguments /tmp/tmpgo.Q5eDch.go:12:6: can inline Read2 /tmp/tmpgo.Q5eDch.go:3:6: can inline main /tmp/tmpgo.Q5eDch.go:8:6: can inline Read1 /tmp/tmpgo.Q5eDch.go:5:8: inlining call to Read2 /tmp/tmpgo.Q5eDch.go:4:14: make([]byte, 2) does not escape /tmp/tmpgo.Q5eDch.go:9:14: make([]byte, 1) escapes to heap
関連
- Stack or Heap? Going Deeper with Escape Analysis in Go for Better Performance。調べている中でio.Readerとio.Writerインターフェースの設計について言及していたのを見つけた
- KDOC 414: インターフェースがヒープにエスケープされるのを見る。調べるきっかけになった