0

私はRMagickを使用して、Rails 3アプリ(Passengerで実行)でかなり単純な画像操作を行っています。破棄を使用しているにもかかわらず、関連するメモリリークを制御しようとしてひどい経験をしています!方法。注意すべき重要な点は、受信画像が透明なPNGである可能性があることです。私は、RMagickが使用するデフォルトの黒ではなく、白の背景に画像を配置したいと考えています。他はPDFかもしれません、その場合私は最初のページを使いたいです。

現在、3.6MBのJPEGのサイズを変更すると、110MBのメモリリークが発生します。

だから、誰かが私のサンプルを見て、おそらく私が間違っているところを見つけることができますか?

    path = 'some/path'
    page_id = "0" 
    in_doc_o = nil
    begin
      in_doc_o = ImageList.new(path+"[#{page_id}]")
      # Create a white background layer
      in_doc_temp = in_doc_o.new_image(in_doc_o.first.columns, in_doc_o.first.rows) { self.background_color = "white" } 
      in_doc = in_doc_o.reverse.flatten_images
      in_doc.format = "jpg"
    rescue
      # Something went wrong so create a dummy 'error' image
      in_doc = ImageList.new("public/images/doc.jpg"+"[#{page_id}]")
    end

    in_doc.change_geometry!('600x200>') { |cols, rows, img| img.resize!(cols, rows) }

    out_blob = in_doc.to_blob() { self.quality = 60 }
    res = save_to_special_storage_device(out_blob)
    mime_type = in_doc.mime_type

    begin        
      in_doc.each {|img| img.destroy!}
    rescue=>e
      Rails.logger.info "rescued attempting destroy on in_doc image list #{e.inspect}"
    end
    begin        
      in_doc_o.each {|img| img.destroy!}
    rescue=>e
      Rails.logger.info "rescued attempting destroy on in_doc_o image list #{e.inspect}"
    end        
    begin
      in_doc.destroy!          
      in_doc_o.destroy! unless in_doc_o.nil?
      in_doc = nil          
      in_doc_o = nil
      in_doc_temp.destroy! if in_doc_temp
      in_doc_temp = nil
    rescue
      Rails.logger.info "rescued attempting image cleanups"
    end
    GC.start

PNGを事前に識別し、空白の白い画像を作成しないことで、もう少しコードを犠牲にしていくつかの問題を節約できると思いますが、テストではまだ60MBをリークしています。これは、解決したい根本的な問題を示唆しています。 。

不思議なことに、またはそうではないが、ほぼ同じサイズの別の画像を使用してテストを再実行した場合、メモリ使用量が2回目に大幅に増加することはありません(幸いなことに)。

特に私がどれだけのメモリを節約できるかという観点から、合理的なアイデアをいただければ幸いです。

4

1 に答える 1

0

まさにあなたが抱えている問題に対処するために書かれた minimagic を試してみてください。

ほとんどのタスクでは、ここにリンクされている minimagic gemで十分です。ImageMagick のコマンドライン ツールを実行します。つまり、新しいプロセスが作成され、実行されてから停止し、メモリが解放されます。RMagic を MiniMagic に置き換えたので、記憶の問題は過去のものとなりました。

于 2012-11-15T21:42:40.353 に答える