Hacker News new | ask | show | jobs
by Atom4966 3725 days ago
> I just wanted to mention that I found out the other day that the Go garbage collector doesn't free memory.

If you mean `free` as it's used in `C`, then I guess technically, it doesn't `free` memory, but I fail to see the practical difference between that and how it it releases memory back to the OS - which is does.

> So your process will never shrink in memory usage

I think you've been mislead. This statement is observably false.

1 comments

> > I just wanted to mention that I found out the other day that the Go garbage collector doesn't free memory.

> If you mean `free` as it's used in `C`, then I guess technically, it doesn't `free` memory, but I fail to see the practical difference between that and how it it releases memory back to the OS - which is does.

Misusing memory overcommitment doesn't count as "freeing" memory. Sure, it happens to mean that the kernel frees the page and provides a new one in its place (which is a Linux-ism and isn't explicitly stated in the man page). MADV_DONTNEED has several quite big issues (it's worse than munmap in almost every category since it has to do an munmap immediately and then create a new page as well). The point is that the process still will get killed if overcommit_ratio is a sane value.

> > So your process will never shrink in memory usage

> I think you've been mislead. This statement is observably false.

Depends how you want to define "memory usage". I defined it implicitly as "sum of size of all mappings given to the process". In other words, how much is committed to the process. That number doesn't go down. RSS does go down, but I'm currently investigating what looks like Go not reusing "unused" pages properly.

If you think there is a problem, you should let the Go devs know about it. I still think all your claim are false.
> I still think all your claim are false.

Well, you can try running the following testcase:

% for i in {1..1000}; do docker run -dit --name shell_$i busybox sh; done

% for i in {1..1000}; do docker rm -f shell_$i; done

You'll notice that /proc/meminfo shows a large amount of overcommited memory. If you look at pprof output from the daemon, there is nowhere near that much memory being used (so it's not a goroutine leak or something like that). If you then re-run the first command the memory still rises, which shouldn't happen because it has ample unused heap space.

So yes, it's a real bug that I'm debugging.