15

こんにちは、

最近、アプリケーションをRails 3.0.4(オンライン開発サーバーでは3.0.5)に更新しました。2.3.10から3.0.4への変更のほとんどは、廃止された、または古いプラグインとgemによるものであり、比較的簡単に解決できました。しかし、1つのことが私を怒らせます:

開発モードでは、すべてのWeb要求により、サーバープロセスは以前よりも約50〜60MB多くのメモリを割り当てます。このメモリは、少なくともすべてではなく、要求後に解放されません10〜20のリクエストの後、すべてのRubyインスタンスが500 MBを超えるRAMを消費しましたが、以前のRails2.3.10インスタンスが200MBを超えることはめったにありませんでした。

これにより、1300テストを実行できなくなります。これは、開発マシンの4GBのRAMがテストの終了前にいっぱいになるためです。が付いた開発モードでのみ発生しますcache_classes = false。cache_classesをtrueに切り替えると、Railsインスタンスは約200MBのメモリを消費し、そこにとどまります。ただし、テスト中は、cache_classes = trueを使用しても、メモリ使用量が増加します。

ObjectSpaceに問い合わせたところ、リクエストごとに、約3500の新しいProc、最大50,000の新しい文字列、3000の新しいハッシュと配列が作成され、解放されていないことがわかりました。これらの文字列(ダンプされた場合)には、プラグインとgem、ドキュメント、ソースコードのコメント、パス名を含むソースコード全体が含まれていました。(なぜ?)

この原因を見つけるために、私が試したのは次のとおりです:(変更するたびに、アプリをハンマーで叩きましたab -n 50。)

  1. 単一のリソースとコントローラー、およびSQLite3DBを使用して新しいRails3アプリケーションを作成しました。メモリ使用量は60MBから始まり、80MB未満にとどまりました。
  2. 'sqlite3'を'pg'に変更し、新しいRails3アプリを既存のPostgresDBにポイントしました。メモリ使用量は110MBから始まり、130MBを超えることはありませんでした。(副次的な質問:PostgresgemがSQLite3gemよりもはるかに多くのメモリを使用するのはなぜですか?)
  3. GemfileとGemfile.lockを壊れたRails3アプリからベアボーンアプリにコピーし、バンドルインストールを実行しました。変更はなく、リクエストの数に関係なく、メモリは約115MBのままでした。
  4. 壊れたRails3アプリで、空の「def FooController; def foo; render:text =>'foo'end;end」を作成しました。メモリ使用量はゆっくりと増加しましたが、リクエスト後に増加が止まることはありませんでした
  5. FooControllerルートを除くすべてのルートを削除しました。変更なし
  6. 以下を除くすべてのGemsを無効にしましたpg, rails, aasm, will_paginate, geokit-rails3, koala, omniauth, paperclip変更なし
  7. ApplicationControllerのすべてのbefore_filterとafter_filter、およびenvironment.rbのすべてのnonessentialを無効にしincludeました。また、boot.rb、environment.rb、application.rbを必要最低限​​のRails 3アプリと同期しました。ただし、5つの比較的単純なオブザーバー、/libとfilter_parametersのファイルの自動読み込みを除きます。変更なし。新しいリクエストごとに、さらに10〜50MBのRAMが消費されました。

ここで何が問題になっているのか、メモリリークがどこにあるのかがわかっている場合は、助けていただければ幸いです。私はOSXSnowLeopardでRails3.0.4を実行し、DebianLennyでRails3.0.5を実行しています。

ありがとうございました!

近づく:

私はすべてのプラグイン、すべてのgem、すべての拡張機能、および自分で作成しなかったすべてのものを削除したので、私のアプリケーションは基本的に裸になっています。特に、これらのプラグインを削除しましacts_as_list, acts_as_tree, asset_packager, forgot_password, fudge_form, fudge_scaffold, paperclippolymorph, query_trace, rails_upgrade, repeated_auto_complete-0.1.0, role_requirement, to_select, validates_url, and ym4r_gmた。

今私のアプリケーション-上記​​のFooControllerだけがまだ機能します!ab -n 1000 -c1-65MBで起動し、 (ApacheBenchを使用して/ fooに1000のHTTP要求を)ハンマーで叩いた後でも、75MBのRAMを超えることはありません。残念ながら、プラグインがなければ、これはまったく機能する唯一のURIでもあります。

少し掘り下げた後、RestfulAuthenticationとActsAs State Machine(AASM)プラグインの組み合わせがメモリリークを引き起こしているようです。https://github.com/Satish/restful-authentication/issues#issue/11も参照してください。理由はまだわかりません。必要最低限​​のプロジェクトで「AASMを含める」だけを実行しても、RAMの使用量が増えるだけではありません。

さらに調査します。

犯人が見つかりました

AASMです。Rails 3では、AASM::xxxオブジェクトインスタンスがリークしているようです。見る

2番目の犯人が見つかりました

rspecで別のメモリリークが発生しました。これにより、AASMを削除した後でも、テストがほとんど耐えられないほど遅くなりました。これは、2つの並列実行rspecタスク(https://github.com/grosser/parallel_testsを使用)が最後にほぼ3GBのメモリを消費したためです。https://github.com/rspec/rspec-core/issues/#issue/321を参照してください。

4

1 に答える 1