う戦略くのメモリ使用量が低いのか。
-
02-07-2019 - |
解決
- 効率的な表現である日付構造を選択し、適切にスケーリングし、必要なことを行います。
- 肥大化するのではなく効率的なデータ構造を使用して機能するアルゴリズムを使用しますが、より簡単なものを使用します。
- 他の場所を探します。 RubyにはCブリッジがあり、RubyよりもCでメモリを意識するのがはるかに簡単です。
他のヒント
PhusionのRuby Enterprise Edition(ガベージコレクションが大幅に改善されたメインラインRubyのフォーク)を見つけて、メモリ使用量に劇的な違いをもたらしました。さらに、インストール(および削除)を非常に簡単にしました。 、必要に応じて)。
ウェブサイトで詳細を確認してダウンロードできます。
それはそれほど重要ではないと思う。 メモリ消費を改善するためにコードを読みにくくすることは、必要の場合にのみ行うべきです。必要に応じて、パフォーマンスプロファイルの特定のケースと、変更が問題に対処することを示す特定のメトリックを持っていることを意味します。
メモリが制限要因となるアプリケーションがある場合、Rubyは最良の選択ではないかもしれません。とは言っても、Railsアプリは一般にMongrelインスタンスごとに約40〜60 MBのRAMを消費することがわかりました。物事のスキームでは、これはそれほど多くありません。
JRubyを使用してJVMでアプリケーションを実行できる場合があります-現在、Ruby VMはメモリ管理とガベージコレクションのJVMほど高度ではありません。 1.9リリースでは多くの改善が加えられており、代替のVMも開発中です。
Ruby開発者はかなりラッキーならないための管理メモリ。
このルビーを割り当てオブジェ、インスタンスなど簡単なもの
100.times{ 'foo' }
割り当て100文字列オブジェクト(文字列は変更可能な、各バージョンが必要で、独自のメモリ割り当).
必ずご利用の場合には、図書室配分を多くるモノのその他の選択肢はない、の選択には、ガベージコレクタます。(ございませんがご要望の多かった/s又はその恐れのあるみなさんは気にしないで、数十msり依頼)
作成のハッシュオブジェクト本当に割り当てによるオブジェクトは、インスタンス
{'joe' => 'male', 'jane' => 'female'}
な配分の1のオブジェクトが7.(一ハッシュ、4つの文字列+2キー文字列)
使いいただけるのであればキーシンボルとしているゴミを収集します。しかしなゴミ収集したいください使用しないで完全に動的なキーのように変換するユーザネームをシンボルの多い国なので、普段から'漏洩'ます。
例: どこかでアプリの使用to_sym、ユーザー名様:
hash[current_user.name.to_sym] = something
できたら何百人ものユーザー、それがokで何が起きている場合は一万人のユーザー?こちらの番号:
ruby-1.9.2-head >
# Current memory usage : 6608K
# Now, add one million randomly generated short symbols
ruby-1.9.2-head > 1000000.times { (Time.now.to_f.to_s).to_sym }
# Current memory usage : 153M, even after a Garbage collector run.
# Now, imagine if symbols are just 20x longer than that ?
ruby-1.9.2-head > 1000000.times { (Time.now.to_f.to_s * 20).to_sym }
# Current memory usage : 501M
注意決して不変換制御の引数をシンボルまたはチェックの引数の前に、することで、容易に否定のサービスです。
も忘れてはいけな入れ子ループより深いレベルでの維持を困難にする。制限を入れ子ループの機能をレベル以下では経験則かのコードperformant.
ここではいくつかのリンクについて:
- Rails / Rack webappをデプロイするときは、REEまたはその他のコピーオンライトフレンドリーなインタープリターを使用します。
- ガベージコレクターの調整( https://www.engineyard.com/blog/tuning-the-garbage-collector-with-ruby-1-9-2 など)
- 追加のコードはメモリを使用するため、使用する外部ライブラリ/宝石の数を削減してください。
- 実際にメモリを集中的に使用するアプリの一部がある場合は、C拡張機能で書き換えるか、他の/より高速/より最適化されたプログラムを呼び出して完了する価値があります(大量のテキストデータを処理する必要がある場合) 、おそらくそのコードをgrep、awk、sedなどの呼び出しに置き換えることができます)
私はルビー開発者ではありませんが、いくつかのテクニックと方法はどの言語にも当てはまると思います:
ジョブに適した最小サイズ変数を使用する
使用していないときに変数と接続を破棄して閉じます
ただし、オブジェクトがある場合は、何度も使用する必要があります。
大きな文字列を操作するループは、小さな文字列で作業を行い、大きな文字列に追加します
適切な(最後にcatchを試す)エラー処理を使用して、オブジェクトと接続が閉じていることを確認します
データセットを扱う場合、必要最小限の値のみを返す
極端な場合を除き、メモリ使用量は心配する必要はありません。メモリ使用量を削減しようとすると、ギガバイトの LOT が購入されます。
スモールメモリソフトウェア-メモリが限られているシステムのパターンをご覧ください。どんな種類のメモリ制約を指定するのではありませんが、RAMを想定しています。 Ruby固有ではありませんが、この本にはいくつかの有用なアイデアがあると思います-パターンはRAM、ROM、セカンダリストレージをカバーし、小さなデータ構造、メモリ割り当て、圧縮、セカンダリストレージ、および小さなアーキテクチャ。
実際に心配する価値があるのは、RMagickだけです。
解決策は、RMagickバージョン2を使用していることを確認し、 Image#destroy!
画像の使用が終了したら
このようなコードは避けてください:
str = ''
veryLargeArray.each do |foo|
str += foo
# but str << foo is fine (read update below)
end
各中間文字列値をStringオブジェクトとして作成し、次の反復でその唯一の参照を削除します。これにより、ガベージコレクションを行う必要のある文字列がますます長くなり、メモリが大量に消費されます。
代わりに、Array#join
:
str = veryLargeArray.join('')
これはCで非常に効率的に実装されており、文字列作成のオーバーヘッドは発生しません。
更新:ジョナスは、以下のコメントで正しいです。私の警告は+=
には当てはまりますが、<<
には当てはまりません。
私はRubyはかなり新しいですが、これまでのところ、これに関して特別なことをする必要はありませんでした(つまり、一般的にプログラマーとしてやりがちなことを超えています)。これはおそらく、メモリが真剣に最適化するのにかかる時間よりも安いためです(私のRubyコードは4〜12 GBのRAMを搭載したマシンで実行されます)。また、私が使用しているジョブが長時間実行されていない(つまり、アプリケーションに依存する)可能性もあります。
Pythonを使用していますが、戦略は似ていると思います。
小さな関数/メソッドを使用して、呼び出し元に戻ったときにローカル変数が自動的にガベージコレクションされるようにします。
大規模な関数/メソッドでは、大きな一時オブジェクト(リストなど)が不要になったら明示的に削除します。リソースをできるだけ早く閉じることも役立ちます。
心に留めておくべきことは、オブジェクトのライフサイクルです。あなたがオブジェクトをあまり渡さない場合、ガベージコレクターは最終的に起動してそれらを解放します。ただし、それらを参照し続けると、ガベージコレクターがそれらを解放するためにいくつかのサイクルが必要になる場合があります。これは、Ruby 1.8で特に当てはまります。Ruby1.8では、ガベージコレクターがマークアンドスイープテクニックの貧弱な実装を使用します。
<!> quot;デザインパターン<!> quot;を適用しようとすると、このような状況に陥ることがあります。オブジェクトを長時間メモリに保持するデコレータのようなものです。例を単独で試してみると明らかではないかもしれませんが、数千のオブジェクトが同時に作成される実際のアプリケーションでは、メモリの増加のコストが大きくなります。
可能な場合、他のデータ構造の代わりに配列を使用します。整数が使用する場合は、フロートを使用しないようにしてください。
gem / libraryメソッドを使用するときは注意してください。メモリが最適化されていない可能性があります。たとえば、Ruby PG :: Resultクラスには、最適化されていないメソッド 'values'があります。多くの追加メモリを使用します。まだ報告していません。
malloc(3)の実装を jemalloc に置き換えると、メモリ消費量がすぐに最大30%削減されます。これを即座に実現するために、「jemalloc」gemを作成しました。
配列を維持しようとしています<!> amp;リスト<!> amp;可能な限り小さいデータセット。ほとんどの現代言語では作成とガベージコレクションが非常に高速であるため、個々のオブジェクトは重要ではありません。
データベースから何らかの巨大なデータセットを読み取る必要がある場合は、すべてをメモリにロードする代わりに、フォワード/オンリー方式で読み取り、少しずつ処理することを確認してください。
多くのシンボルを使用しないでください。プロセスが強制終了されるまでメモリ内に残ります。これは、シンボルがガベージコレクションされないためです。