Draft: Run GC.compact before forking Puma workers
What does this MR do?
We recently looked into the new GC compaction feature of Ruby 2.7: https://gitlab.com/gitlab-org/memory-team/memory-team-2gb-week/-/issues/1
The conclusion is that there is a noticeable improvement in shared memory use right after forking Puma workers, however, this effect deteriorates over time to approach a memory layout similar to what we would see without compaction.
On the other hand, moving used objects slots together increases the likelihood of free pages, which when in excess can be released back to the OS. Along with tuning GC and malloc over time this will benefit overall memory use going forward.
Compaction requires a full re-org of the Ruby heap, i.e. it's expensive, but not prohibitively so. On my Core i9 it adds a little under 1s:
Cold start:
{"severity":"INFO","time":"2020-11-30T15:16:29.631Z","correlation_id":null,"message":"Heap compaction finished","duration_ms":993.3959369991499,"pid":6}
After SIGUSR2
:
{"severity":"INFO","time":"2020-11-30T15:18:38.347Z","correlation_id":null,"message":"Heap compaction finished","duration_ms":934.2203660016821,"pid":6}
It won't run when bouncing individual workers, since that will not result in a before_fork
event.
For now I have put this change behind an environment variable. We cannot use feature toggles here since we cannot rely on a DB connection to have been set up at this point during boot.
Does this MR meet the acceptance criteria?
Conformity
-
Changelog entry -
Documentation (if required) -
Code review guidelines -
Merge request performance guidelines -
Style guides -
Database guides -
Separation of EE specific content
Availability and Testing
-
Review and add/update tests for this feature/bug. Consider all test levels. See the Test Planning Process. -
Tested in all supported browsers -
Informed Infrastructure department of a default or new setting change, if applicable per definition of done
Related to #288042 (closed)