-gcflags "-m -l"
をつけてビルドすると何が起こっているのかヒントが見れます。
shell
1>go build -gcflags "-m -l"
2# closure
3.\main.go:7:14: leaking param: next
4.\main.go:6:6: moved to heap: store
5.\main.go:7:9: func literal escapes to heap
6.\main.go:16:13: ... argument does not escape
7.\main.go:16:15: b("あ") escapes to heap
8.\main.go:17:13: ... argument does not escape
9.\main.go:17:15: b("い") escapes to heap
10.\main.go:18:13: ... argument does not escape
11.\main.go:18:15: b("う") escapes to heap
それぞれのメッセージの意味は以下の通り。
leaking param
関数が終わっても変数が生き続けるけど、メモリリークではありません。
move to heap
変数はヒープメモリに退避されました。
func literal escapes to heap
関数リテラルはヒープメモリに退避されました。
argument does not escape
関数に渡された引数は退避されません。
関数 escapes to heap
関数の戻り値はヒープメモリに退避します。
結論
- 関数リテラル=クロージャーの中で親スコープのstoreにアクセスしているのを発見したのでヒープに退避しましたということ。
- ヒープに退避された場合、だれかが参照を残している限り破棄されずに保持されます。
- つまり、b変数のスコープアウトが発生すれば芋づる式にヒープに退避されたものはガベージコレクタによって破棄されます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2022/06/04 01:50
2022/06/04 03:26