【发布时间】:2014-11-07 19:39:19
【问题描述】:
我最近在大型数据集上运行了一些用 Go 编写的数字代码,并且遇到了内存管理问题。在尝试分析问题时,我用三种不同的方式测量了我的程序的内存使用情况:使用 Go 的 runtime/pprof 包,使用 unix time 实用程序,以及手动添加我分配的数据的大小。这三种方法没有给我一致的结果。
下面是我正在分析的代码的简化版本。它分配几个切片,将值放在每个索引处,并将它们中的每一个放在父切片中:
package main
import (
"fmt"
"os"
"runtime/pprof"
"unsafe"
"flag"
)
var mprof = flag.String("mprof", "", "write memory profile to this file")
func main() {
flag.Parse()
N := 1<<15
psSlice := make([][]int64, N)
_ = psSlice
size := 0
for i := 0; i < N; i++ {
ps := make([]int64, 1<<10)
for i := range ps { ps[i] = int64(i) }
psSlice[i] = ps
size += int(unsafe.Sizeof(ps[0])) * len(ps)
}
if *mprof != "" {
f, err := os.Create(*mprof)
if err != nil { panic(err) }
pprof.WriteHeapProfile(f)
f.Close()
}
fmt.Printf("total allocated: %d MB\n", size >> 20)
}
使用命令$ time time -f "%M kB" ./mem_test -mprof=out.mprof 运行它会产生输出:
total allocated: 256 MB
1141216 kB
real 0m0.150s
user 0m0.031s
sys 0m0.113s
这里的第一个数字 256 MB 是从 unsafe.Sizeof 计算的数组的大小,第二个数字 1055 MB 是 time 报告的。运行 pprof 工具会导致
(pprof) top1
Total: 108.2 MB
107.8 99.5% 99.5% 107.8 99.5% main.main
这些结果以您期望的方式平滑扩展,用于更小或更大长度的切片。
为什么这三个数字不排列得更紧密?
【问题讨论】:
-
只需在我的机器上运行您的代码并得到“总分配:1024 MB”(OS X 10.9.5)
-
还有你用的是什么版本的go,你用的目标架构是什么?
-
我的示例代码中有错误,现在我已更正。我正在为 linux/amd64 运行 Go 1.3.3