雾宝石泄漏记忆

时间:2014-09-18 21:40:21

标签: ruby fog

我编写了一个脚本,通过我的Rackspace cloudfiles容器递归下载并检索每个文件的副本,因此我有一个本地备份,以防Rackspace受到流星和/或hindenbugs的攻击。<​​/ p>

但是,我的脚本在下载文件时显然会以线性比例泄漏内存。

基本上我有一个看起来像这样的方法:

def download_file(fog_file, destination_path)
  data = fog_file.body
  File.open(destination_path, 'w') { |f| f.write(data) }
end

据我所知,由于Fog的性质,我无法避免将整个文件加载到内存中,但我认为Ruby会在每次download_file调用后释放内存(或具有释放内存的能力)。毕竟,data变量超出了范围。

不幸的是,当我查看系统监控时,内存使用量会以线性速度增长,直到它消耗掉所有可用内存,此时脚本崩溃。

我在这里做错了什么?

我在Ubuntu上使用Ruby 2.1.2。

1 个答案:

答案 0 :(得分:1)

您可以避免以两种方式将整个文件加载到内存中。

首先,您可以在100kb(或更少)chucks中检索文件:

service = Fog::Storage.new({ provider: 'Rackspace', 
                             # ... auth config
                             connection_options: {chunk_size: 102_400} # 100 KB in bytes                        
})

directory = service.directories.get "dir"

File.open((destination_path, 'w') do | f |
  directory.files.get("my_file_on_cloud.png") do | data, remaining, content_length |
    f.syswrite data
  end
end

其次,您可以使用雾检索文件URL,然后使用OpenUri下载并保存文件:

require 'open-uri'

file = open(file.public_url).read
File.open(destination_path, 'w') { |f| f.write(file) }

第一种方法直接写入目标文件,第二种方法创建Tempfile实例(在文件系统上创建临时文件)。试试两个。