我正在使用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这表明我会遇到一个基本问题喜欢解决。
奇怪或不是,如果我用另一张大小相同的图像重新运行测试,内存使用量不会再次大幅跳跃(幸运的是)。
任何合理的想法都会受到赞赏,特别是考虑到我可以节省多少内存。
答案 0 :(得分:0)
尝试使用minimagic,这是为了解决你遇到的问题。
对于大多数任务,the minimagic gem linked here就足够了。它运行ImageMagick的命令行工具,这意味着创建一个新进程,它运行,然后停止,释放内存。我们用MiniMagic取代了RMagic,我们的记忆困境已成为过去。