当我使用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
答案 0 :(得分:2)
您可能会遇到“过早优化”综合症。语言规范说 nothing 关于如何分配make()
分配的内存的确切内容。
例如,符合Go的实现可能会对make([]foo, ...)
的函数进行彻底的分析,并证明:
append()
未在此切片值上调用。在这种情况下,切片的后备存储可能正在堆栈上分配。
当然我已经解释了,但是再次,语言规范中没有声明它的语义。目前有两个成熟的Go实现(其中一个来自Google,被称为gc
,gccgo
)还有更多(llvmgo
似乎有很好的机会辜负),他们都有自己的特点。
因此,请考虑阅读pprof
和Go概述,并进行个人资料(但是真实的)代码。
在the mailing list中搜索单词“profile”,“profiling”,“heap AND profile”,“CPU AND profile”和“pprof”将为您提供大量的见解。