【问题标题】:How does Go allocate memory in make or new calls?Go 如何在 make 或 new 调用中分配内存?
【发布时间】:2015-10-11 17:35:53
【问题描述】:

当我使用 make 或 new 调用创建新切片或结构时:

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

【问题讨论】:

标签: memory memory-management go dynamic-memory-allocation


【解决方案1】:

您可能会遇到“过早优化”综合症。语言规范没有说明make() 分配的内存将如何分配。

例如,符合标准的 Go 实现可能会对执行 make([]foo, ...) 的函数进行彻底分析,并证明:

  1. 返回的 slice 值没有脱离函数的作用域。
  2. append() 未在此切片值上调用。
  3. 它没有传递给任何被调用函数的切片值。

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

当然我在夸大其词,但同样,语言规范中并未声明其语义。目前有两个成熟的 Go 实现(一个来自 Google,称为 gcgccgo)还有更多(llvmgo 似乎有很好的机会实现),它们都有自己的特点.

所以请考虑阅读 pprof 和一般的 Go 分析,并进行分析示例(但真实)代码。

the mailing list 中搜索“profile”、“profiling”、“heap AND profile”、“CPU AND profile”和“pprof”这些词将为您提供大量相关信息。

同时考虑thisthis

【讨论】:

  • 仅供参考,我正在尝试实现缓存服务器,因此内存管理不是过早的优化。
  • @NeoWang,那么您可能对sync.Poolexternal memory poolsinternal memory pools 感兴趣。
  • @NeoWang,总的来说,我强烈建议您在邮件列表中提出问题,明确提及您的任务并征集 cmets。对于此类研究,SO 是一种错误的媒介,真的。
  • github.com/golang/groupcache是memcache作者的一个库,设计目标不同。
猜你喜欢
  • 2016-09-12
  • 2012-04-20
  • 2020-10-05
  • 2012-12-22
  • 2013-05-09
  • 1970-01-01
  • 2021-05-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多