Do I need to set a map to nil in order for it to be garbage collected?

huangapple go评论82阅读模式
英文:

Do I need to set a map to nil in order for it to be garbage collected?

问题

假设我有一个简单的映射,键类型为字符串,值类型为自定义结构体,就像这样:map[string]*struct

我用许多不同的值填充了这个映射,其中很多值在一段时间后将不再使用。

所以我不确定Golang的垃圾回收器是否会自动清理我的映射,还是我需要自己清理。然后我在另一个问题的答案中找到了这个回答:https://stackoverflow.com/questions/23229975/is-it-safe-to-remove-selected-keys-from-golang-map-within-a-range-loop/23231539#23231539

这看起来像是垃圾回收器不会自动清理,我唯一的解决办法是在需要释放一些内存时将我的映射设置为nil。

这是真的吗?还是有其他方法可以在不丢失映射中的值的情况下进行清理?

英文:

Let's say I have a simple map with string as keytype and a self-defined struct as valuetype. Like this: map[string]*struct

I populate this map with a lot of different values and a lot of these values will never be used again after a certain period of time.

So I wasn't sure whether the golang garbage collector will clean up my map for me or I need to do it myself. Then I came across this answer on a different question: https://stackoverflow.com/questions/23229975/is-it-safe-to-remove-selected-keys-from-golang-map-within-a-range-loop/23231539#23231539

This makes it look like the garbage collector won't do it for me and my only solution is to set my map to nil if i want to free up some memory every now and then.

Is this true? Or is there another way to do it without losing values in my map that are not 'inactive'?

答案1

得分: 6

为了全面回答这个问题,我们需要弄清楚问题的确切内容。

对于标题的问题:
> 我需要将一个 map 设置为 nil 才能进行垃圾回收吗?

不需要,一旦 map 的值超出作用域,它就会像其他值一样被垃圾回收。

> 我用很多不同的值填充了这个 [map[string]*stuct] map,并且很多这些值在一段时间后将不再使用。

你展示的这个示例 map 包含指针值,只要它们包含在 map 中,它们指向的值就不会被回收。从 map 中删除值(使用 delete 或将键设置为其他值)将允许指针引用的内存被回收。在确保垃圾回收的情况下,不需要对 map 进行特殊处理。

现在,map 的内部结构目前不会被压缩,小的值(包括指针和任何小于 128 字节的值)直接存储在哈希桶中。删除这些条目后,拥有数百万条目的 map 不会立即变小,所以如果你需要释放该内存,最好将你想要保留的剩余值复制到一个新的 map 中。这类似于拥有一个不再需要的大型切片,除了几个值之外,你需要将剩余的值复制到一个新的切片中以释放原始的底层数组。

英文:

To try and answer this fully, we need to figure out what the question is exactly.

For the title question:
> Do I need to set a map to nil in order for it to be garbage collected?

No, once the map value is out of scope, it will be garbage collected like any other value.

> I populate this [map[string]*stuct] map with a lot of different values and a lot of these values will never be used again after a certain period of time.

This example map you show contains pointer values, and for as long as they are contained in the map, the values to which they point will never be collected. Deleting the values from the map (using delete or setting the key to another value) will allow the memory referenced by the pointers to be collected. There is no special handling that needs to be done around a map to ensure garbage collection.

Now, the internal structures of a map are not currently compacted, and small values (including pointers, and anything under 128 bytes) are stored directly in the hash buckets. A map with millions of entries isn't going to get smaller immediately after deleting those entries, so if you need to free that memory it's best to copy the remaining values you want to a new map. This is analogous to having a large slice that's no longer needed except for a few values, where you need to copy the remaining values to a new slice to free the original backing array.

答案2

得分: 0

你可以从映射中使用delete()方法删除单个条目,即使在迭代过程中也可以。如果该条目的值对其他任何内容都不可访问(且足够大),它们将被垃圾回收。

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

英文:

You can delete() individual entries from the map, even while iterating over it. If the entry's value is unreachable from anything else (and it is big enough), they will be GC'ed.

The question you looked at referenced some old code (you can look at the source yourself), memory should be emptied after objects are removed from the map.

huangapple
  • 本文由 发表于 2016年4月20日 22:59:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/36747776.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定