为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
四季花海 2021-10-25 16:13: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) = 0xc000000000munmap(0xc000000000, 65536)             = 0mmap(NULL, 262144, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7efdd1017000mmap(0xc208000000, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xc208000000mmap(0xc207ff0000, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xc207ff0000mmap(0xc000000000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xc000000000mmap(NULL, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7efdd1007000mmap(NULL, 1439992, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7efdd0ea7000
查看完整描述

1 回答

?
墨色风雨

TA贡献1853条经验 获得超6个赞

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

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

  1. 返回的切片值不会转义函数的作用域。

  2. append() 不在此切片值上调用。

  3. 它没有传递给任何被调用函数的切片值。

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

当然我在夸大其词,但同样,在语言规范中没有声明它的语义。目前有两种成熟的 Go 实现(一种源自谷歌,被称为gcgccgo),还有更多的实现(llvmgo似乎很有可能实现),它们都有自己的特点。

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

在邮件列表中搜索“profile”、“profiling”、“heap AND profile”、“CPU AND profile”和“pprof”这几个词,将会为您提供很多关于它的见解。

还要考虑这个这个


查看完整回答
反对 回复 2021-10-25
  • 1 回答
  • 0 关注
  • 196 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信