一尘不染

Go如何在拨打电话或拨打新电话时分配内存?

go

当我用make或new调用创建新的slice或struct时:

s := make([]int64, 10, 100)
o := new(MyStruct)

Go通过内存分配系统调用分配多少内存?它是否预分配了内存,以便后续调用不会触发新的系统调用?

我问这个问题是因为我需要在代码中频繁分配内存。我不确定是否需要自己实现一个内存分配器,还是可以依靠Go来完成肮脏的工作。如果Go确实预分配了内存,我可以自定义要分配的块大小吗?

我在Go中编写了一些实验代码,并在strace下运行该代码,但我不了解Go对mmap系统调用的作用:

mmap(0xc000000000, 65536, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xc000000000
munmap(0xc000000000, 65536)             = 0
mmap(NULL, 262144, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7efdd1017000
mmap(0xc208000000, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xc208000000
mmap(0xc207ff0000, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xc207ff0000
mmap(0xc000000000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xc000000000
mmap(NULL, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7efdd1007000
mmap(NULL, 1439992, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7efdd0ea7000

阅读 316

收藏
2020-07-02

共1个答案

一尘不染

您可能在这里遭受“过早优化”综合症。语言规范 没有 说明将如何精确分配分配的内存make()

例如,一个合格的Go实现可能会对功能进行彻底的分析,make([]foo, ...)并证明:

  1. 返回的切片值不会转义函数的范围。
  2. append() 未在此分片值上调用。
  3. 切片值,它没有传递给任何调用的函数。

在这种情况下,可以在堆栈上直接分配片的后备存储。

当然,我正在汇总,但再次说明,此语言的语义未在语言规范中声明。目前,有两种成熟的Go实施(一种起源于Google,被称为gcgccgo),还有更多的实现(llvmgo似乎有很多机会实现),而且它们都有其独特之处。

因此,请考虑pprof总体上阅读和Go分析,并进行个人资料示例(但实际)代码。

在邮件列表中搜索单词“ profile”,“
profiling”,“ heap AND profile”,“ CPU AND profile”和“ pprof”将为您提供很多见解。

也考虑这个这个

2020-07-02