用pprof分析map和slice的記憶體呼叫

xing393939發表於2022-02-25

學習了go的map和slice的記憶體結構,可以從理論上得知儲存同等數量相同元素,map佔用的記憶體比slice大,那麼怎麼去驗證這一點呢,下面我用pprof實際驗證一下。

假設元素型別定義如下:

type canceler struct {
    code int
    data uintptr
}

先測試slice的記憶體佔用,程式碼如下:

func sliceMemoryUse(num int) {
    max := make([]canceler, num, num)
    _ = &max
}

func main() {
    num := 1024 * 1024
    sliceMemoryUse(num)
    f, _ := os.Create("mem.out")
    pprof.WriteHeapProfile(f)
    f.Close()
}
/*
這裡用到了runtime.pprof包來收集記憶體資訊,如果要收集cpu的資訊,則使用如下程式碼:
f, err := os.Create("cpu.out")
pprof.StartCPUProfile(f)
// do some stuff
pprof.StopCPUProfile()
*/

使用pprof檢查一下

go tool pprof --alloc_space mem.out
      flat  flat%   sum%        cum   cum%
      16MB   100%   100%       16MB   100%  main.sliceMemoryUse (inline)
         0     0%   100%       16MB   100%  main.main
         0     0%   100%       16MB   100%  runtime.main

再測試map的記憶體佔用,程式碼如下:

func mapMemoryUse(num int) {
    max := make(map[canceler]struct{}, num)
    _ = &max
}

func main() {
    num := 1024 * 1024
    mapMemoryUse(num)
    f, _ := os.Create("mem.out")
    pprof.WriteHeapProfile(f)
    f.Close()
}

使用pprof檢查一下

go tool pprof --alloc_space mem.out
      flat  flat%   sum%        cum   cum%
   38.25MB   100%   100%    38.25MB   100%  main.mapMemoryUse (inline)
         0     0%   100%    38.25MB   100%  main.main
         0     0%   100%    38.25MB   100%  runtime.main
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章