New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

runtime: maps do not shrink after elements removal (delete) #20135

genez opened this Issue Apr 26, 2017 · 5 comments


None yet
6 participants

genez commented Apr 26, 2017

What version of Go are you using (go version)?

go version go1.8 windows/amd64

What operating system and processor architecture are you using (go env)?

set GOARCH=amd64
set GOBIN=
set GOEXE=.exe
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOOS=windows
set GOPATH=C:\dev\Go
set GOROOT=C:\Go
set GOTOOLDIR=C:\Go\pkg\tool\windows_amd64
set GCCGO=gccgo
set CC=gcc
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0
set CXX=g++
set PKG_CONFIG=pkg-config
set CGO_CFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2

What did you do?

See example on playground:
(edit: forgot to remove sleeps and changed the number of elements)

What did you expect to see?

removing elements from m1 map should release memory.

What did you see instead?

total allocated memory is always increasing

In the example the issue is not so relevant, but in my production scenario (several maps with more than 1million elements each) I can easily get OOM error, and the process is being killed.
Also I don't know if memstats.Alloc is the right counter to expose here, but I can observe the issue with regular process management tools in linux (e.g. top or htop)

@bradfitz bradfitz changed the title from maps do not shrink after elements removal (delete) to runtime: maps do not shrink after elements removal (delete) Apr 26, 2017


This comment has been minimized.


bradfitz commented Apr 26, 2017

@bradfitz bradfitz added this to the Unplanned milestone Apr 26, 2017


This comment has been minimized.


josharian commented Apr 26, 2017

I'm surprised there isn't a dup of this already in the issue tracker.

Yes, maps that shrink permanently currently never get cleaned up after. As usual, the implementation challenge is with iterators.

Maps that shrink and grow repeatedly used to also cause leaks. That was #16070, fixed by CL 25049. I remember hoping when I started on that CL that the same mechanism would be useful for shrinking maps as well, but deciding it wouldn't. Sadly, I no longer remember why. If anyone wants to investigate this issue, I'd start by looking at that CL and thinking about whether that approach could be extended to shrinking maps.

The only available workaround is to make a new map and copy in elements from the old.


This comment has been minimized.

tandr commented Sep 4, 2018

just an observation - adding runtime.GC() after last loop of copy/delete brings memory down to about the same size (well, lower actually) as at "Alloc After M1" point


This comment has been minimized.

hixichen commented Sep 24, 2018

Any update on this issue?

we load 1 Million entry into map. No matter we try to delete the value or set the map nil, seems the memory is always increasing until OOM.


This comment has been minimized.


mvdan commented Sep 24, 2018

@hixichen: see @josharian's workaround above:

The only available workaround is to make a new map and copy in elements from the old.

That is, you have to let the entire map be garbage-collected. Then all its memory will eventually be made available again, and you can start using a new and smaller map. If this doesn't work, please provide a small Go program to reproduce the problem.

As for progress - if there was any, you'd see it in this thread.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment