我正在使用 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,这表明我想解决一个基本问题.
奇怪的是,如果我用大约相同大小的另一张图像重新运行测试,内存使用量第二次不会显着增加(幸运的是)。
任何合理的想法都会受到赞赏,尤其是考虑到我可以节省多少内存。