Go如何在make或new调用中分配内存?

时间:2015-07-22 02:51:51

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

当我使用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

1 个答案:

答案 0 :(得分:2)

您可能会遇到“过早优化”综合症。语言规范说 nothing 关于如何分配make()分配的内存的确切内容。

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

  1. 返回的切片值不会转义函数的范围。
  2. append()未在此切片值上调用。
  3. 它未传递给任何被调用函数的切片值。
  4. 在这种情况下,切片的后备存储可能正在堆栈上分配。

    当然我已经解释了,但是再次,语言规范中没有声明它的语义。目前有两个成熟的Go实现(其中一个来自Google,被称为gcgccgo)还有更多(llvmgo似乎有很好的机会辜负),他们都有自己的特点。

    因此,请考虑阅读pprof和Go概述,并进行个人资料(但是真实的)代码。

    the mailing list中搜索单词“profile”,“profiling”,“heap AND profile”,“CPU AND profile”和“pprof”将为您提供大量的见解。

    还要考虑thisthis