Skip to content

Commit

Permalink
Manually compact GC before fork (#2093)
Browse files Browse the repository at this point in the history
Rub 2.7.0 introduced `GC.compact` which allows manual compaction of Ruby slots. A good time to do this is before forking so that memory fragmentation can be reduced.

- https://www.ruby-lang.org/en/news/2019/12/17/ruby-2-7-0-rc1-released/
- https://www.youtube.com/watch?v=1F3gXYhQsAY

One issue with memory fragmentation when forking is that while a page in memory might have only one free slot, as that slot is written to after fork, the entire page is written so the benefit of CoW optimizations are greatly reduced. Manually compacting GC reduces the number of pages with empty slots.

This PR manually compacts memory right before Puma forks and after other `before_fork` hooks are called.
  • Loading branch information
schneems committed Dec 18, 2019
1 parent 1bec245 commit b646fc5
Show file tree
Hide file tree
Showing 3 changed files with 3 additions and 0 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Expand Up @@ -52,6 +52,7 @@ matrix:
- rvm: ruby-head
env: jit=yes
- rvm: truffleruby
- rvm: 2.7.0-preview3

allow_failures:
- rvm: jruby-9.2.9.0
Expand Down
1 change: 1 addition & 0 deletions History.md
Expand Up @@ -4,6 +4,7 @@
* Add pumactl `thread-backtraces` command to print thread backtraces (#2053)
* Configuration: `environment` is read from `RAILS_ENV`, if `RACK_ENV` can't be found (#2022)
* `Puma.stats` now returns a Hash instead of a JSON string (#2086)
* `GC.compact` is called before fork if available (#2093)

* Bugfixes
* Your bugfix goes here (#Github Number)
Expand Down
1 change: 1 addition & 0 deletions lib/puma/cluster.rb
Expand Up @@ -486,6 +486,7 @@ def run
@master_read, @worker_write = read, @wakeup

@launcher.config.run_hooks :before_fork, nil
GC.compact if GC.respond_to?(:compact)

spawn_workers

Expand Down

0 comments on commit b646fc5

Please sign in to comment.