Let’s try to figure out memory usage of Go. |
package main
|
import (
"fmt"
"runtime"
"strconv"
"unsafe"
)
|
|
Unlike C, there is no #pragma pack in Go, the real memory allocation depends on its implementation. |
type T struct {
B uint8 // is a byte
I int // it is int32 on my x86 32 bit PC
P *int // it is int32 on my x86 32 bit PC
S string
SS []string
}
|
var p = fmt.Println
|
|
In this case, the |
func memUsage(m1, m2 *runtime.MemStats) {
p("Alloc:", m2.Alloc-m1.Alloc,
"TotalAlloc:", m2.TotalAlloc-m1.TotalAlloc,
"HeapAlloc:", m2.HeapAlloc-m1.HeapAlloc)
}
func main() {
|
Here is a tricky to get pointer size |
const PtrSize = 32 << uintptr(^uintptr(0)>>63)
p("PtrSize=", PtrSize)
p("IntSize=", strconv.IntSize)
|
var m1, m2, m3, m4, m5, m6 runtime.MemStats
runtime.ReadMemStats(&m1)
t := T{}
runtime.ReadMemStats(&m2)
p("sizeof(uint8)", unsafe.Sizeof(t.B),
"offset=", unsafe.Offsetof(t.B))
p("sizeof(int)", unsafe.Sizeof(t.I),
"offset=", unsafe.Offsetof(t.I))
p("sizeof(*int)", unsafe.Sizeof(t.P),
"offset=", unsafe.Offsetof(t.P))
p("sizeof(string)", unsafe.Sizeof(t.S),
"offset=", unsafe.Offsetof(t.S))
|
|
Slice is a structure of Pointer, Len and Cap. Detail here |
p("sizeof([]string)", unsafe.Sizeof(t.SS),
"offset=", unsafe.Offsetof(t.SS))
|
We can see the this structure is 4 + 4 + 4 + 8 + 12 = 32 bytes There are 3 padding bytes of first t.B expanded to 4 bytes. |
p("sizeof(T)", unsafe.Sizeof(t))
|
We will see 0 bytes, because it is on stack, so sizeof is the proper method to tell how much memory allocated. |
memUsage(&m1, &m2)
|
Even string assignment is in stack. |
runtime.ReadMemStats(&m3)
t2 := "abc"
runtime.ReadMemStats(&m4)
memUsage(&m3, &m4)
|
map will alloc memory in heap |
runtime.ReadMemStats(&m5)
t3 := map[int]string{1: "x"}
runtime.ReadMemStats(&m6)
memUsage(&m5, &m6)
|
fmt.Println(t2, t3) // prevent compiler error
}
|
$ go run memory-and-sizeof.go
PtrSize= 32
IntSize= 32
sizeof(uint8) 1 offset= 0
sizeof(int) 4 offset= 4
sizeof(*int) 4 offset= 8
sizeof(string) 8 offset= 12
sizeof([]string) 12 offset= 20
sizeof(T) 32
Alloc: 0 TotalAlloc: 0 HeapAlloc: 0
Alloc: 0 TotalAlloc: 0 HeapAlloc: 0
Alloc: 144 TotalAlloc: 144 HeapAlloc: 144
abc map[1:x]
|
Previous example: Text Template.
Next example: Optimize String Append.