[][]string 与包含 []string 的结构的内存使用情况
Posted
技术标签:
【中文标题】[][]string 与包含 []string 的结构的内存使用情况【英文标题】:Memory usage of [][]string vs struct containing []string 【发布时间】: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 := recordvalues: 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%)。
【参考方案1】:
对于那些在 go 1.12 和 go 1.15 之间使用的人,debug.FreeOSMemory()
不会将空闲内存返回给操作系统,因此 htop/top 会显示错误的数字或者如果您依赖 RSS 来监控您的应用程序,那就错了。
这是因为 Golang (1.12 - 1.15) 中的运行时使用 MADV_FREE
而不是 MADV_DONTNEED
。
Go 1.16 恢复为 MADV_DONTNEED
。
请找到更改日志图片和更改日志 URL here。
请升级以获得有关内存使用情况的可预测分析。如果你想使用 GoLang(1.12-1.15) 并且仍然想使用 MADV_DONTNEED
,请使用 GODEBUG=madvdontneed=1
./main 运行你的二进制文件。
【讨论】:
我认为这不能回答问题。 这没有提供问题的答案。一旦你有足够的reputation,你就可以comment on any post;相反,provide answers that don't require clarification from the asker.以上是关于[][]string 与包含 []string 的结构的内存使用情况的主要内容,如果未能解决你的问题,请参考以下文章
[C#] string 与 String,大 S 与小 S 之间有关字符串的秘密(整理中...)