runtime包提供了操作runtime的一些函数,控制协程等。
package main
import (
"runtime"
"fmt"
"time"
)
const COLS = 10000000
func main() {
PrintMemUsage()
var data [][]int
for i := 0; i<5; i++ {
a := make([]int, 0, COLS)
data = append(data, a)
PrintMemUsage()
time.Sleep(time.Second)
}
//并不会强制内存回收
data = nil
PrintMemUsage()
// 强制内存回收
runtime.GC()
PrintMemUsage()
}
func PrintMemUsage() {
var m runtime.MemStats
runtime.ReadMemStats(&m)
fmt.Printf("Alloc = %v MiB", MB(m.Alloc))
fmt.Printf("\tTotalAlloc = %v MiB", MB(m.TotalAlloc))
fmt.Printf("\tSys = %v MiB", MB(m.Sys))
fmt.Printf("\tNumGC = %v\n", m.NumGC)
}
func MB(b uint64) uint64 {
return b / 1024 / 1024
}
运行结果如下:
Alloc = 0 MiB TotalAlloc = 0 MiB Sys = 67 MiB NumGC = 0
Alloc = 76 MiB TotalAlloc = 76 MiB Sys = 201 MiB NumGC = 0
Alloc = 152 MiB TotalAlloc = 152 MiB Sys = 201 MiB NumGC = 1
Alloc = 228 MiB TotalAlloc = 228 MiB Sys = 333 MiB NumGC = 2
Alloc = 305 MiB TotalAlloc = 305 MiB Sys = 465 MiB NumGC = 2
Alloc = 381 MiB TotalAlloc = 381 MiB Sys = 466 MiB NumGC = 3
Alloc = 381 MiB TotalAlloc = 381 MiB Sys = 466 MiB NumGC = 3
Alloc = 0 MiB TotalAlloc = 381 MiB Sys = 466 MiB NumGC = 4
需要注意的是,GC调用会阻塞当前调用者,有可能会阻塞整个go进程。