質問: [] GC.start puts "memsize: #{ObjectSpace.memsize_of_all / 1024} KB, rss: #{`ps -o rss= #{Process.pid}`.chomp} KB" end end ``` こんな感じのコードを書くと、実行結果は以下のようになります。 ``` memsize: 4125 KB, rss: 8016 KB memsize: 5113 KB, rss: 9000 KB memsize: 6092 KB, rss: 10000 KB memsize: 7071 KB, rss: 11000 KB memsize: 8050 KB, rss: 11984 KB memsize: 2473 KB, rss: 11988 KB memsize: 3452 KB, rss: 11988 KB memsize: 4431 KB, rss: 11988 KB memsize: 5410 KB, rss: 11988 KB memsize: 6389 KB, rss: 11988 KB memsize: 7368 KB, rss: 11988 KB memsize: 2473 KB, rss: 11988 KB memsize: 3452 KB, rss: 11988 KB memsize: 4431 KB, rss: 11988 KB memsize: 5410 KB, rss: 11988 KB memsize: 6389 KB, rss: 11988 KB memsize: 7368 KB, rss: 11988 KB memsize: 2473 KB, rss: 11988 KB memsize: 3452 KB, rss: 11988 KB memsize: 4431 KB, rss: 11988 KB memsize: 5410 KB, rss: 11988 KB memsize: 6389 KB, rss: 11988 KB memsize: 7368 KB, rss: 11988 KB memsize: 2473 KB, rss: 11988 KB ``` 時間を伸ばしたり、外からpsコマンドを実行したりしましたが、どうやってもRSSが減りません。 Rubyオブジェクトに割り当てられたメモリは解放されているのに、せっかく開放したメモリをOSには返却してくれないようです。 このプロセスに限れば確保したメモリを再利用できるからいいのですが、サーバー上には他のプロセスも動いてるわけでやはり使わなくなったメモリはOSに戻したいです。 Rubyの仕様上、難しいことでしょうか?
回答: Ruby ではオブジェクトを破棄しても free されにくい実装と記憶しています。(結構前の話なので今は変わっているかも?) またCレベルの話をすると、free を呼んでもOSにメモリを返さず、次に malloc した際に再割当するような実装も多く存在します。 ということで、一般的にはメモリの解放によっても占有メモリが減らない前提でプログラミングすることになろうかと思います。 どうしてもということであれば、メモリが解放されるようなRubyのバージョン (もし存在すれば) とmalloc/freeの実装の組み合わせを固定して開発する必要があるでしょう。