让我们说我有一个简单的地图,其中字符串为keytype,自定义结构为valuetype。像这样:map[string]*struct
我用很多不同的值填充这个地图,很多这些值在一段时间后永远不会再使用。
所以我不确定golang垃圾收集器是否会为我清理我的地图,或者我自己需要这样做。然后我在另一个问题上遇到了这个答案:Is it safe to remove selected keys from Golang map within a range loop?
这使得看起来垃圾收集器不会为我做这件事,我唯一的解决办法是将我的地图设置为nil,如果我想不时地释放一些内存。
这是真的吗?或者是否有另一种方法可以做到这一点而不会丢失我的地图中没有“不活动”的值?
答案 0 :(得分:5)
为了尝试完全回答这个问题,我们需要弄清楚问题究竟是什么。
标题问题:
我是否需要将地图设置为nil才能进行垃圾回收?
不,一旦地图值超出范围,它将像任何其他值一样被垃圾收集。
我使用许多不同的值填充此[
map[string]*stuct
]地图,并且在一段时间后,许多这些值将永远不会再次使用。
您显示的此示例地图包含指针值,只要它们包含在地图中,它们指向的值就永远不会被收集。从地图中删除值(使用delete
或将密钥设置为另一个值)将允许收集指针引用的内存。在地图周围不需要进行特殊处理以确保垃圾收集。
现在,地图的内部结构当前没有被压缩,并且小值(包括指针和128字节以下的任何内容)直接存储在散列桶中。删除这些条目后,包含数百万条目的地图不会立即变小,因此如果您需要释放该内存,最好将所需的剩余值复制到新地图中。这类似于除了少量值之外不再需要大切片,您需要将剩余值复制到新切片以释放原始支持阵列。
答案 1 :(得分:0)
您可以delete()
来自地图的单个条目,即使在迭代它时也是如此。如果条目的值无法从其他任何地方访问(并且足够大),则它们将被GC编辑。
你看到的问题引用了一些旧代码(你可以自己查看源代码),在从地图中删除对象后应该清空内存。