0

我正在使用 RMagick 在 Rails 3 应用程序(在乘客上运行)中进行一些相当简单的图像处理。尽管使用了破坏,但我在尝试控制相关的内存泄漏时却遇到了可怕的经历!方法。需要注意的重要一点是,传入的图像可能是透明的 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,这表明我想解决一个基本问题.

奇怪的是,如果我用大约相同大小的另一张图像重新运行测试,内存使用量第二次不会显着增加(幸运的是)。

任何合理的想法都会受到赞赏,尤其是考虑到我可以节省多少内存。

4

1 回答 1

0

试试 minimagic,它是为解决您遇到的问题而编写的。

对于大多数任务,此处链接的 minimagic gem就足够了。它运行 ImageMagick 的命令行工具,这意味着一个新进程被创建,它运行,然后停止,释放内存。我们用 MiniMagic 取代了 RMagic,我们的记忆问题已经成为过去。

于 2012-11-15T21:42:40.353 回答