[][]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 查看[]stringrecord 使用的内存的实际大小。请注意,它们相等的事实实际上可能很少。 我确实用基准测试了 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 的结构的内存使用情况的主要内容,如果未能解决你的问题,请参考以下文章

String包含在Java哪个包里

[C#] string 与 String,大 S 与小 S 之间有关字符串的秘密(整理中...)

string.substring 与 string.take

CString与string的区别

QString与std::string 有中文时的转换操作

QString与std::string 有中文时的转换操作