【问题标题】:How does go perform map/slice reallocations?go 如何执行 map/slice 重新分配?
【发布时间】:2018-09-21 00:14:59
【问题描述】:

我在the runtime 中找不到它,但我想知道在重新分配映射或切片时,go 如何决定可能需要多少内存。所以当我们看这个时(同样适用于切片):

test := map[int]string{}
for i := 0; i < 1000; i++ {
  test[i] = fmt.Sprintf("test-%d", i)
}

一开始会分配多少内存,在循环期间会发生多少次重新分配?

我问这个是因为我想弄清楚是否存在应用自定义重新分配策略有意义的情况(即使用数组而不是切片,并在需要时按可能符合我的因素增长数组应用程序的要求)。

【问题讨论】:

  • 你可以用make(map[int]string, 1000)为1000个元素“预分配”一个大容量的地图,所以不会发生重新分配。
  • 是的,没错,但如果我不能呢?可能有些情况我无法预测总长度,但我可能知道当它超过容量时它会增长到哪些维度。
  • 即使你弄清楚它在你的配置中是如何工作的,最好不要依赖这样的内部结构,因为它可能会根据所使用的编译器、版本、操作系统和架构而有所不同。要了解如何“测量”它,这可能很有用:How much memory do golang maps reserve?
  • 这是一个实现细节,因此平台、编译器和版本之间可能/确实会有所不同。
  • append and runtime.growslice — 对 1.8 仍然有效;没有检查更高版本。

标签: go memory-management


【解决方案1】:

它的要点是,粗略地说,除了边缘情况,容量通常会增加一倍,并且无法控制。如果需要,您可以实现自己的增长/复制机制。你可以在这里阅读源代码:https://go.googlesource.com/go/+/master/src/runtime/slice.go#89

【讨论】:

  • 感谢您的回答,该链接有帮助。我专门寻找L112。看起来容量 1024 的因子 1.25。
  • 不确定我的问题是否不清楚,但是在达到地图容量时是否可以通过分配新地图(假设是双倍大小)来获得某种控制然后将旧地图复制到新地图中?
  • @tworabbits 是的,这是可能的,但由于您无法访问地图的底层结构,因此使用公开的 API 进行复制可能会非常慢,没有它您会更好。
猜你喜欢
  • 1970-01-01
  • 2017-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-07
相关资源
最近更新 更多