-
Notifications
You must be signed in to change notification settings - Fork 3k
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
Add process flag 'heap_growth' #4939
base: master
Are you sure you want to change the base?
Conversation
Should this: |
Can we have some context as to why you are adding this feature? In what scenarios will it provide benefits? |
CT Test Results 3 files 125 suites 37m 20s ⏱️ Results for commit 575e9ab. ♻️ This comment has been updated with latest results. To speed up review, make sure that you have read Contributing to Erlang/OTP and that all checks pass. See the TESTING and DEVELOPMENT HowTo guides for details about how to run test locally. Artifacts// Erlang/OTP Github Action Bot |
Hey @sverker , this seems terribly useful. If I'm grokking correctly, this is terribly useful in the context of long lived processes which may have to consume lots of messages but do not hold them in state (i.e., proc heap). Is that right? |
The idea of this PR was to optimize process heap memory consumption at the expense of CPU load caused by more frequent GCs when a process creates lots of live data. With the current (normal) GC strategy, we exponentially grow the size of the new-heap based on the amount of terms that survived the last GC. This is done before we know how much data will survive this GC. We assume the process will continue to create lots of live data and we want to give it more heap capacity to do that. A larger heap will prolong the time until next GC and that will also give the data more time to die. If the process then stops creating live data and enters a more passive period, then it might get "stuck" with a large inflated new-heap with lots of capacity that it does not use. The We had a real use case where memory consumption was a high priority concern. However, they gained almost nothing from this PR when tested. That's why it has not been merged. |
Precisely. We have processes in our system at work that suffer because of this, such that we have to set fullsweep_after to a very low value (or zero in some cases), in addition to some more expensive work arounds. This is mainly per passing complex terms to processes and then putting them in ets. We are actually going to make changes to one such set of procs that gets around all this via passing and storing serialized binaries via term_to_binary/1 and friends. That said, we have some other procs that could maybe benefit from this.
I'm happy to try a patch out if there's still interest in this. |
This branch is currently based on OTP-24.3, what do you need? You can always try merge forward to newer versions. I don't think the merge conflicts you might get will be particularly hard to solve. |
I can merge it forward I'm quite sure, I'll report back soon. |
Hey @sverker it took me a minute on this, but I can say I saw no substantial improvement. |
New process flag
heap_growth
to enable more memory conservative garbage collections.normal
is the default old behavior. When allocating heap capacity during GC it takes into account the amount of live terms that survived the last GC. A process continuously generating live data will thus grow its heap capacity over time and get less frequent but larger GCs.low
is the new memory conservative option. The GC maintains a bounded small heap capacity which results in more frequent but smaller GCs.In both cases, terms that survive two GCs will be moved to the old-heap whose size calculation is not affected by this PR.
heap_growth can be set/read per process with
process_flag(heap_growth, low | normal)
process_info(Pid, heap_growth)
spawn_opt(_, [{heap_growth, low | normal}])
and node wise with
system_flag(heap_growth, low | normal)
system_info(heap_growth)
erl -hg low