-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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: scavenging doesn't reduce reported RSS on darwin, may lead to OOMs on iOS #29844
Comments
Furthermore, using gomobile Running similar code on iOS (replacing Confirmed on android this is not the case, ie, works the same as on linux. |
Can you try Go 1.12beta2? https://golang.org/dl/#go1.12beta2 |
Reproduced with Go 1.12beta2 on OSX. same thing.. |
I'm not sure this demonstrates an actual bug. We use It's kind of an unfortunate state. It would be really nice if Darwin reported "committed RSS" or some such stricter meaning of RSS. Without that, we're left guessing if Go is really keeping those pages to itself or not. Loading up the system with other memory-hungry programs might shed some light on whether we're actually releasing memory correctly or not. That's tricky to do reliably, but might be the only way to make progress here. See #14521. |
I was able to get the OS to take back the memory. Modify your program to add this loop at the end of the existing loop (so we just give back the memory and sit idle):
Then run the following program with argument 10 (to use ~10GB of DRAM):
(My machine has 32GB DRAM, YMMV.) The program prints its original memory size until I run the memory hog program, then transitions to a much lower memory usage:
|
@randall77 Thanks, I'll try your suggestion, but in the meanwhile I'll give some more context. |
Confirmed your memhog program makes the OS (on darwin) take back the memory. On iOS however (arm64) I'm getting oom.. Any suggestions of where to go from here? |
Thinking about replacing |
reproduced memory hog in iOS/arm46, had to find the sweet spot of allocating a large enough amount of memory to trigger OS to take back these pages without causing OOM. Even then, not all memory that is released by scavenger is returned, it seems the OS takes some of it, and the amount is not stable across runs.. |
OK I think I found a way to make OSX and iOS behave as expected: running this C code on these platforms and instrumenting it will clearly show the difference in memory returned to OS, no other memory pressure is needed: while (true) {
int size = 1024*1024*10;
u_char *x = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1 ,0);
memset(x, 1, size);
sleep(2);
madvise(x, size, MADV_FREE_REUSABLE);
sleep(2);
} |
I agree with @randall77, AFAICT this is working as intended. On Linux for go1.11.4 and below we always use Replacing With that said, I haven't heard of |
|
I found (through StackOverflow [1]) an old version of libmalloc which gives some indication: https://opensource.apple.com/source/libmalloc/libmalloc-53.1.1/src/magazine_malloc.c.auto.html It appears that you need to first call The fact that it's not in the manpage makes me nervous too, but apparently Chrome is using it (https://github.com/chromium/chromium/blob/master/base/memory/discardable_shared_memory.cc#L377). I also found this through StackOverflow [1]. [1]: https://stackoverflow.com/questions/7718964/how-can-i-force-macos-to-release-madv-freed-pages |
Well, looks like Chromium has more information on this, which confirms my suspicions: https://github.com/chromium/chromium/blob/master/base/memory/discardable_shared_memory.cc#L254 The comment there then links to https://bugs.chromium.org/p/chromium/issues/detail?id=823915. Following the trail of Chromium bugs finally leads me to https://bugs.chromium.org/p/chromium/issues/detail?id=708797#c25, where it seems the suggestion was made by someone who knows about Darwin kernel internals. It still would be nice to get official information about these flags, but I don't know where to look at this point. If we're to add this, the plan would be to update |
@mknyszek with the current implementation of Does the runtime handle segfaults in a graceful way if the memory is still mapped? |
When Later, when an application then touches a page in that region, one of two things can happen:
For an example of system that needs |
Thanks a lot for taking the time for this thorough explanation. |
Change https://golang.org/cl/159117 mentions this issue: |
OK, so I uploaded a change which moves the runtime to using The program at the top of this issue isn't "fixed" because it's output still reports that the RSS doesn't decrease.
@omribahumi @DanielZlotin Please feel free to try out the patch and confirm. I haven't tried it on iOS, but it seems to work on amd64 Macs. |
Thank you all for the thorough explanation and prompt responses. FYI, instead of using |
I guess we can close this once the patch lands |
What version of Go are you using (
go version
)?and
Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (
go env
)?go env
Output - linuxgo env
Output - MacOSWhat did you do?
https://play.golang.org/p/K5ZvGZ4hmdH
What did you expect to see?
As expected, on linux, I see the delta in RSS roughly matching the memory returned to the OS by scavenger (calling
debug.FreeOSMemory()
)What did you see instead?
In contrast, on OSX I see the scavenger reporting memory being returned, but this is not reflected in RSS (and other places like ActivityMonitor and Instruments)
Is this expected? Am I missing anything?
The text was updated successfully, but these errors were encountered: