9

これを実行し、OSX アクティビティ モニターで Ruby プロセスのメモリ消費を監視すると、メモリは約 3 MB/秒で増加します。

トランザクションを削除すると、メモリ消費量は約半分になりますが、メモリ フットプリントは増え続けます。本番アプリで、メモリ消費が原因で Heroku がプロセスを強制終了するという問題があります。

メモリを増やさない方法で以下を行う方法はありますか? 行をコメントアウトして.saveも問題ありませんが、もちろんこれは解決策ではありません。

ActiveRecord::Base.transaction do
  10000000.times do |time|
    puts "---- #{time} ----"
    a = Activity.new(:name => "#{time} Activity")
    a.save!(:validate => false)
    a = nil
  end
end

を使用してこれを実行していdelayed_jobます。

4

2 に答える 2

5

このa = nil行は不要なので、削除できます。

ループするたびに多くのオブジェクトを作成しています。2 つの文字列、2 つのハッシュ、Activity オブジェクトです。特に 1,000 万回ループしているときに、メモリ使用量が高くなっても不思議ではありません。このコードを記述するためのよりメモリ効率の良い方法はないようです。

メモリ使用量を減らすために私が考えることができる唯一の方法は、ガベージ コレクターをx回の反復ごとに手動で開始することです。おそらく、Ruby の GC は十分に積極的ではありません。ただし、コードを大幅に遅くするため、反復ごとに呼び出す必要はありません。おそらく、100回の反復ごとに開始点として使用し、そこから進むことができます. 最も効果的なものをプロファイリングしてテストする必要があります。

GCのドキュメントはこちらです。

于 2012-05-05T14:28:27.620 に答える