Hacker News new | ask | show | jobs
by tapirl 1325 days ago
Yes, Go maps never shrink. This is good for most use cases in practice. Because in practice, map entry deletions happen seldom. And when map entry deletions are needed, users often hope maps don't shrink, to avoid potential later unnecessary memory allocations and entry moves. For example, I only do map entry deletions in one of my projects, In the project, I clear all entries of a map and re-use the map to avoid making new allocations. The current design satisfies my need well.

This is more an optimization than a memory leak.

To avoid the kind-of memory leak, just make a new map and discard the old one.

3 comments

That's easily resolved with an ensureCapacity(size) method, or the other way around with shrinkToFit(size).

maps being magic without a real interface means exposing new API surface is difficult though.

A few times I have wished for a way to grow maps, but generally to shrink maps I don't think there's any big advantage to a built-in rather than your own function making a new one. (It would only cover the case where you know you want to shrink but don't know if you need to shrink because you don't know how many elements you removed or overestimated by, which I think is pretty unusual.)
Personally, I am not against the proposal to add a "shrink(aMapOrSlice)` builtin function. In fact, there are more builtin functions on my wish list, such as "concat(slices)" and "decap(aSlice)".

It is just that the Go core team have their own philosophy.

The article gives a common place example where this could be an issue, so I don’t know what you mean by “in practice” here.
The parent said “most” so both can be true: most maps don’t need to shrink and the example in the article is a valid case where shrinking a map would be desirable. This seems obvious so I’m confused by your confusion. :)
I think you’re referring to

> However, let’s say we want to store one hour of data. Meanwhile, our company has decided to have a big promotion for Black Friday: in one hour, we may have millions of customers connected to our system. But a few days after Black Friday, our map will contain the same number of buckets as during the peak time. This explains why we can experience high memory consumption that doesn’t significantly decrease in such a scenario.

> What are the solutions if we don’t want to manually restart our service to clean the amount of memory consumed by the map?

I don’t see that as a strong argument for making the implementation of maps more complex by adding some auto- shrinking. If your process survived Black Friday with a map full of items, why would it run out of memory after it with a map that’s mostly empty but didn’t return bookkeeping memory to the heap? Your process likely will keep running. There may be a slight performance drop because cache lookups become more likely to lead to cache misses, but otherwise, the typical system won’t care much about the use of virtual memory space.

> Yes, Go maps never shrink. This is good for most use cases in practice.

Why is it that every shortcoming of Go is spun by its advocates into something that is actually a good thing?

In what languages do maps shrink? You may be surprised.
C# has trim excess but I do t think Java does, ...just the two I checked.

https://learn.microsoft.com/en-us/dotnet/api/system.collecti...

Java HashMap does not shrink.
Sorry that's a typo. don't*
Why is it that haters of go refuse to engage with the actual argument?

Edit: rephrasing your comment “why is it that every time I say something misleading about go people disagree with me?”