- Implement Process.warmup by byroot · Pull Request #7662 · ruby/ruby
- Feature #18885: End of boot advisory API for RubyVM - Ruby master - Ruby Issue Tracking System
- Ruby本体に
Process.warmup
というメソッドが追加される- 現時点のステータスとしては、 一度 Implement
Process.warmup
by byroot · Pull Request #7346 · ruby/ruby がマージされたんだけどCIコケてrevert→再チャレンジ中
- 現時点のステータスとしては、 一度 Implement
- アプリケーション側でbootが終わったぞ、というときに使う
- unicornやpumaなどのpreforkするタイプのアプリケーションはforkするので、そのタイミングでいい感じにCoWフレンドリーになるようにしたい
- 例えば ko1/nakayoshi_fork を使うとforkの時点でGCを4回実行*1して、すべてのオブジェクトを古い世代にすることでCoWフレンドリーにする
- オブジェクトが何回GCを生き延びたか、というフラグを持っているのでなにもしないとGCのタイミングでオブジェクトが書き換わり、親プロセスと子プロセスで差分ができてしまう
- nakayoshi_fork自体は単純に4回GCを実行している
- けど、Rubyの内部に「いまいるオブジェクトを全部古い世代にする」APIがあればそれ使ったほうが効率的ですよね
- あと「複数のワーカプロセスをforkで生成する」ケースだとforkにフックをかけるやり方だとforkする回数分同じ処理が実行されるので効率が悪い
- そこでアプリケーションの起動が終わったタイミングでおもむろに
Process.warmup
を実行し、そこでもろもろいい感じにCoWフレンドリーにしてやると良い - とりあえず上記PRではGC、GC.compact、いまいるオブジェクトを古い世代にするということを
Process.warmup
のタイミングでやっている - 他にもメソッドや定数のインラインキャッシュをキャッシュに載せておく、とかもっと最適化の余地がある模様
- 例えば ko1/nakayoshi_fork を使うとforkの時点でGCを4回実行*1して、すべてのオブジェクトを古い世代にすることでCoWフレンドリーにする
- Ruby3.3だとpumaやunicornのメモリ消費量が減る、といいう未来がありそう
- 普通のRailsアプリケーションでどれくらい減るのか気になる
- puma4->5のタイミングでnakayoshi_forkを有効にして17%メモリ使用量が削減したぞ、という人がいた
- Rubyの最適化、もうあらかた実施済みなのかな、と思ってたけどまだやる余地あるんですね…
*1:3回GCを生き延びたら古い世代になる認識なんだけどなんで4回なんでしょうね…?