雑なメモ書き

気楽にいきます

GoのメモリにおけるHeapの確認 (1)

コード

  • 単純にポインタを返すからheapかと言われると
  • インライン展開で最適化されてそうじゃなくなるケースがあるようだ
package main

func makeHeap() *[]int {
    v := []int{}
    return &v
}

func main() {
    for i := 0; i < 1000; i++ {
        _ = makeHeap()
    }
}

インライン展開無しでheapを確認する

  • -lを使用するとインライン展開を無しに出来る
  • vはheapへ行く
go run -gcflags '-m -l' main.go
# command-line-arguments
./main.go:5:9: &v escapes to heap
./main.go:4:2: moved to heap: v
./main.go:4:12: []int literal escapes to heap

この状態でtraceすると、heapにデータがのっていることがわかる

f:id:hiroyukim:20190226150036p:plain

インライン展開つきでheapを確認する

  • -lを取り除くとインライン展開される
go run -gcflags '-m' main.go
# command-line-arguments
./main.go:3:6: can inline makeHeap
./main.go:10:15: inlining call to makeHeap
./main.go:5:9: &v escapes to heap
./main.go:4:2: moved to heap: v
./main.go:4:12: []int literal escapes to heap
./main.go:10:15: main []int literal does not escape
./main.go:10:15: main &v does not escape

この状態でtraceをするとheapが使われていないことが分かる

f:id:hiroyukim:20190226150100p:plain

コンパイルオプションについて

参照