Reputation: 536
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: Is it safe to remove selected keys from Golang map within a range loop?
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'?
Upvotes: 5
Views: 9588
Reputation: 1746
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.
Upvotes: 0
Reputation: 109417
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.
Upvotes: 6