16

Merb を使用して Web アプリケーションを開発しており、安全で安定した画像処理ライブラリを探しています。以前は PHP で Imagick を使用していましたが、Ruby に移行して RMagick を使い始めました。しかし問題がある。メモリ リークの原因となる実行時間の長いスクリプト。いくつかの解決策が存在しますが、どれが最も安定しているかはわかりません。それで、あなたはどう思いますか?

現在、私のアプリは、PHP で画像を処理するために作成した内部 API を使用しています。他のアプリケーションと一緒に別のサーバーで実行されるため、大きな問題ではありません。しかし、それは良いアーキテクチャではないと思います。

とにかく、実用的なヒントを検討します。

4

5 に答える 5

11

私もこの問題に遭遇しました-解決策はガベージコレクションを強制することです。

画像変数を新しい画像に再割り当てしたら、GC.startを使用して、古い参照がメモリから解放されていることを確認します。

RMagickの新しいバージョンでは、destroyと呼ぶこともできると思います。あなたがそれを処理し終えたときに画像に。

この2つを組み合わせると、おそらく確実にカバーされますが、実際のパフォーマンスへの影響はわかりません(ほとんどの場合、無視できると思います)。

または、 ImageMagickコマンドラインクライアントのラッパーであるmini-magickを使用することもできます。

于 2009-06-06T01:07:03.817 に答える
8

RMagick を使用する場合、完了したらイメージを破棄することを忘れないことが重要です。そうしないと、大量のイメージ セットを操作するときに /tmp ディレクトリがいっぱいになります。たとえば、destroy! を呼び出す必要があります。

require 'RMagick'

Dir.foreach('/home/tiffs/') do |file|
    next if file == '.' or file == '..'
        image = Magick::Image.read(file).first
        image.format = "PNG"
        image.write("/home/png/#{File.basename(file, '.*')}.png")
        image.destroy!
end
于 2013-12-04T20:43:40.003 に答える
5

実際には、これは Ruby 固有の問題ではなく、他のインタープリターも同様に共有しています。具体的な問題は、Ruby の GC が、外部ライブラリではなく、Ruby 自体によって割り当てられたメモリしか認識しないことです (Ruby のメモリ管理機能を使用するライブラリは例外です)。つまり、Ruby のメモリ空間にある ImageMagick-Object は非常に小さいのですが、ImageMagick が管理する空間にある画像は大きいのです。したがって、これ自体はリークではありませんが、リークのように動作します。プロセスが特定の制限 (8MB が標準) を下回っている場合、Ruby ガベージ コレクターは起動しません。ImageMagick は Ruby 空間で大きなオブジェクトを作成しないため、おそらく起動することはありません。したがって、新しいプロセスを生成する提案された方法を使用するか、exec を使用します。もう 1 つの気の利いた方法は、すべてのタスクに対して fork する画像処理サービスをバックエンドに配置することです。

これらの問題に対処し、より優れた API を作成しようとする Timothy Paul Hunter (RMagick の作成者) による MagickWand呼ばれる別のライブラリがあります。ただし、これはアルファ版であり、ImageMagick のかなり新しいリリースが必要です。

于 2009-06-06T11:06:08.377 に答える
-1

これは ImageMagick によるものではありません。これは Ruby 自体が原因であり、よく知られた問題です。私の提案は、プログラムを 2 つの部分に分割することです。メモリをほとんど割り当てず、システムの制御のみを処理する長時間実行部分と、実際に処理作業を行う別のプログラムです。長期実行制御プロセスは、それが生成する子プロセスの作業を見つけるのに十分なだけ行う必要があり、子プロセスはその特定の作業項目のすべての処理を行う必要があります。

別のオプションは、2 つを組み合わせたままにしておくことですが、作業単位が完了した後、execプロセスを同じプログラムの新たに開始されたバージョンに置き換えるために使用します。これにより、別の作業項目が検索され、それが処理され、それ自体が再度実行されます。

これは、作業項目がかなり大きいことを前提としており、ImageMagick を使用している場合はほぼ確実にそうです。そうでない場合は、新しいプロセスを生成し、Ruby インタープリターにプログラム全体を再解析させるオーバーヘッドが少し大きくなりすぎることに気付くでしょう。これに対処するには、プログラム自体を再実行する前に、より多くの作業単位 (たとえば、10 または 100) を行うようにします。

于 2009-06-06T08:21:37.243 に答える