Ruby: mallocでマルチスレッドプログラムのメモリが倍増する理由(翻訳)|TechRacho by BPS株式会社

解決策としては以下2つ。

  1. メモリアリーナを削減する
    • MALLOC_ARENA_MAX を 2-4 に設定する
  2. jemallocを使う
    • malloc → jemalloc に変更
    • LD_PRELOAD で動的に読み込み可能
  3. GC compaction

本番でRubyとPumaまたはSidekiqを使うときは常にjemallocを使うことをおすすめしたいと思います。

プロダクションの Rails サーバーの利用メモリがひたすら増加していくような挙動を観測したとき、どう対応するのがよいですか? - Quora

太古の昔から現在に至るまで、Railsのメモリ使用量がじわじわ増え続ける問題は解決できていません。というのも、これは使われないメモリへの参照が残るバグとしてのmemory leakではなくて、ちゃんと開放してるにもかかわらずメモリ使用量が減らないmemory bloatだからです。

なぜmemory bloatが起きるのか?ですが、これは主にメモリのフラグメンテーション(断片化)の問題です。メモリを確保したり開放したりを繰り返すうちに、再利用しにくい小さい隙間がだんだん増えていくという現象です。

この断片化はRubyレベルだけでなく、さらに下のメモリアロケータレベルでも発生するので、実態はかなり複雑です。 後者については、Glibc malloc特有の挙動があって、PumaやSidekiqなどのスレッドをヘビーに使う環境ではjemallocに置き換えただけでかなり改善するという報告も多数あります。

jemallocs vs tcmallocs vs mimalloc

jemalloc 以外にも allocator がいろいろある。

それぞれ Meta(Facebook), Google, MS などのビッグテックが関わっている。

ベンチマーク