Memory management 我是否需要将map设置为nil才能对其进行垃圾收集?

Memory management 我是否需要将map设置为nil才能对其进行垃圾收集?,memory-management,go,garbage-collection,Memory Management,Go,Garbage Collection,假设我有一个简单的映射,其中字符串作为keytype,自定义结构作为valuetype。如下所示:map[string]*struct 我用很多不同的值填充这张地图,其中很多值在一段时间后将不再使用 所以我不确定果朗垃圾收集器是否会帮我清理地图,还是我需要自己清理。然后我在另一个问题上找到了这个答案: 这使得垃圾收集器看起来不会为我做这件事,我唯一的解决方案是,如果我想时不时地释放一些内存,就将map设置为nil 这是真的吗?或者有没有其他方法可以在不丢失地图中非“非活动”的值的情况下执行此操作

假设我有一个简单的映射,其中字符串作为keytype,自定义结构作为valuetype。如下所示:
map[string]*struct

我用很多不同的值填充这张地图,其中很多值在一段时间后将不再使用

所以我不确定果朗垃圾收集器是否会帮我清理地图,还是我需要自己清理。然后我在另一个问题上找到了这个答案:

这使得垃圾收集器看起来不会为我做这件事,我唯一的解决方案是,如果我想时不时地释放一些内存,就将map设置为nil

这是真的吗?或者有没有其他方法可以在不丢失地图中非“非活动”的值的情况下执行此操作?

您可以
delete()
从地图中删除单个条目,即使在对其进行迭代时也是如此。如果条目的值无法从其他任何地方访问(并且它足够大),它们将被GC’ed


您看到的问题引用了一些旧代码(您可以自己查看源代码),从映射中删除对象后,内存应该清空。

要尝试完整地回答这个问题,我们需要弄清楚问题的确切含义

关于标题问题:

我是否需要将map设置为nil才能对其进行垃圾收集

不,一旦映射值超出范围,它将像任何其他值一样被垃圾收集

我用许多不同的值填充这个[
map[string]*stuct
]映射,其中许多值在一段时间后将不再使用

您显示的示例映射包含指针值,只要指针值包含在映射中,就永远不会收集指针值所指向的值。从映射中删除值(使用
delete
或将键设置为另一个值)将允许收集指针引用的内存。无需围绕地图进行特殊处理以确保垃圾收集


现在,映射的内部结构当前没有被压缩,小值(包括指针和128字节以下的任何值)直接存储在散列桶中。具有数百万条目的映射不会在删除这些条目后立即变小,因此如果需要释放内存,最好将剩余的值复制到新映射。这类似于拥有一个除了少数值之外不再需要的大片,您需要将剩余值复制到一个新片以释放原始备份阵列。

GC收集所有无法访问的内存。将收集两个映射以及从映射中删除的值。地图结构可能会被压缩,也可能不会被压缩,但这与正在收集的值是分开的。我不确定你到底在问什么。垃圾收集器不会清除映射中的条目,因为它们被映射引用(假设映射本身是可访问的)。如果地图中有不再需要的条目,则应将其删除。如果将映射中特定键的值设置为nil,则该映射项指向的结构将被垃圾收集,假设它无法通过其他方式访问。那么verran关于删除而不是释放内存的建议是不正确的?@Siebertschoutteen你刚刚链接到这个问题。我想你指的是-答案是肯定和否定的。桶永远不会被清理。如果映射正在存储一个值类型(如
int
),则该
int
的存储在存储桶中,因此除非将映射置零,否则它也永远不会被清除。但是如果映射正在存储指针,那么这意味着指针的存储将保持不变,但是如果没有任何东西指向它,则指向的值将是GC。从那时起,删除的代码除了从C转换为Go之外没有发生任何变化。这是一个大问题,但它仍然没有巩固桶。我认为Verran说得有点不准确,但基本上还是正确的。它可能引用了一些旧代码,但我找不到任何来源来证明你说的是真的?他们什么时候改的?我很快阅读了go 1.5和1.6发行说明,但找不到任何关于它的信息。我非常确定memclr in将回收内存中的值。我认为Verran关于钥匙的信息是准确的,但关于values@matt.s:
memclr
将某个内存区域的字节归零,它不会为该值回收空间。使用
GODEBUG=gctrace=1
运行此操作,您将看到删除所有键后的集合没有任何作用,并且在可以收集映射值本身之前,堆不会完全释放。@JimB,我不确定这一点。如果您给GC工作的时间/需要,它看起来会回收大部分时间。如果你看这个例子,为什么内存会下降?让我把这个弄对。如果我将剩余的值复制到一个新的映射(这里我们谈论的是数以百万计的条目),而不是什么都不做或删除不再需要的条目,这肯定会对我的内存使用产生良好的影响?@Siebertschoutteen:如果时间权衡对你来说是值得的,那么是的。回答这个问题最好的方法就是简单地测试一下,看看。这就是我需要知道的!你说“地图的内部结构没有被压缩”。我想这意味着以前被现在删除的条目使用的内存块被保留了下来。然后是否将这些重新用于添加到地图的新项目?如果是这样的话,那么在大多数情况下,仍然有他们在身边并不成问题。实际上,如果有什么不同的话,它可能会加速新的插入,因为这些内存块随时可用。