2

Is it possible to find out the memory usage of global variables in Go?

For example have a look at this code:

package main

import (
    "fmt"
    "math/rand"
    _ "net/http/pprof"
    "os"
    "runtime"
    "runtime/pprof"
    "time"
)

var globalByteArray1, globalByteArray2 []byte

func main() {
    rand.Seed(time.Now().Unix())
    globalByteArray1 = make([]byte, 10*1024*1024)
    rand.Read(globalByteArray1)
    memoryUsage()
    globalByteArray2 = make([]byte, 20*1024*1024)
    rand.Read(globalByteArray2)
    memoryUsage()
    fmt.Println(globalByteArray1[len(globalByteArray1)-1], globalByteArray2[len(globalByteArray2)-1])
    file, _ := os.Create("heap")
    pprof.WriteHeapProfile(file)
    file.Close()
    fmt.Println(globalByteArray1[len(globalByteArray1)-1], globalByteArray2[len(globalByteArray2)-1])
}

func memoryUsage() {
    var m runtime.MemStats
    runtime.ReadMemStats(&m)
    fmt.Println(m.Alloc/1024/1024, "MB")
}

This code prints the following output which is fine.

10 MB
30 MB
209 214
209 214

I thought to myself maybe pprof can show me the global variables. But it actually made me more confused.

pprof-graph pprof-flame

So I have two questions:

  1. Can I profile the global variables and see the memory usage of each one?
  2. Why is pprof showing 10MB only? What happened to globalByteArray2?
Hirbod Behnam
  • 577
  • 2
  • 7
  • 26
  • You can’t “profile” a variable, it’s just a value. If you want to know the size of the allocated slice use `cap` – JimB Sep 19 '21 at 16:28
  • 1
    From the documentation: The heap profile reports statistics as of the most recently completed garbage collection; it elides more recent allocation to avoid skewing the profile away from live data and toward garbage. If there has been no garbage collection at all, the heap profile reports all known allocations. – Burak Serdar Sep 19 '21 at 16:35
  • Plus profiling is done via sampling, so it’s not an appropriate tool to find single allocations. – JimB Sep 19 '21 at 16:37
  • @BurakSerdar Oh I didn't know that. Yeah putting `runtime.GC()` before `pprof.WriteHeapProfile(file)` have answered my second question. Thanks! – Hirbod Behnam Sep 19 '21 at 16:41
  • @JimB So if it's not possible, can you write an answer which says it is not possible so I can select it as answer? – Hirbod Behnam Sep 19 '21 at 16:42
  • 1
    this answer provide a way to compute the size of a variable, not only its type descriptor. https://stackoverflow.com/a/62612320/4466350 –  Sep 19 '21 at 17:34
  • @mh-cbon That's also one way to do it! Thanks. I might profile the memory usage of my program by hardcoding all global variables and using that library. – Hirbod Behnam Sep 20 '21 at 04:22

0 Answers0