【发布时间】:2019-07-09 13:46:32
【问题描述】:
当附加到 [][]string 分析时,显示应用使用了大约 145MiB 的内存。
defer profile.Start(profile.MemProfile).Stop()
f, _ := os.Open("test.csv") // 100 MiB File
r := csv.NewReader(f)
var records [][]string
for {
values, err := r.Read()
if err == io.EOF {
break
}
records = append(records, values)
}
将切片存储在结构中并附加应用程序使用大约 260MiB 的内存时。
defer profile.Start(profile.MemProfile).Stop()
type record struct {
values []string
}
f, _ := os.Open("test.csv") // 100 MiB File
r := csv.NewReader(f)
var records []record
for {
values, err := r.Read()
if err == io.EOF {
break
}
r := record{values: values}
records = append(records, r)
}
感觉就像在第二个例子中使用了两倍的内存。有人可以解释为什么第二个示例使用更多内存吗?
【问题讨论】:
-
record和[]string的大小相同。您如何衡量已用内存? -
有人能解释一下为什么第二个例子使用更多的内存吗?不,因为我怀疑第二个实际上使用了更多的内存。可能是您测量的人工制品。
-
一些杂七杂八的事情: 1)在这样的问题中,应该包括确切的 Go 版本和平台信息(GOOS/GOARCH); 2)我会尝试将此案例隔离到基准测试中并使用
-benchmem运行它; 3) 您还可以尝试在GOGC=off下将您的隔离案例作为独立程序运行,并在其开始和结束之前使用runtime.ReadMemStats对内存使用情况进行采样以查看差异; 4) 使用unsafe.SizeOf查看[]string和record使用的内存的实际大小。请注意,它们相等的事实实际上可能很少。 -
我确实用基准测试了 2 个版本,它们的内存使用情况相同。
-
作为参考,这是我测试它的方式:play.golang.org/p/hH7zGgexHKx 请保存在您的文件系统中并使用
go test -bench . -benchmem运行它,并告诉我们您得到了什么。我得到几乎相同的内存使用和分配(差异小于 0.01%)。
标签: go memory struct memory-leaks slice