我有一项在生产环境中运行的作业,用于处理 xml 文件。
xml 文件总共约为 4k,大小为 8 到 9 GB。
处理后我们得到 CSV 文件作为输出。我有一个 cat 命令,它将所有 CSV 文件合并到我得到的单个文件中:
Errno::ENOMEM:无法分配内存
on cat
(反引号)命令。
以下是一些细节:
- 系统内存 - 4 GB
- 交换 - 2 GB
- 红宝石:1.9.3p286
文件处理使用nokogiri
and saxbuilder-0.0.8
.
这里,有一个代码块将处理 4,000 个 XML 文件,输出保存在 CSV 中(每个 xml 1 个)(抱歉,由于公司政策,我不打算分享它)。
以下是将输出文件合并到单个文件的代码
Dir["#{processing_directory}/*.csv"].sort_by {|file| [file.count("/"), file]}.each {|file|
`cat #{file} >> #{final_output_file}`
}
我在处理过程中拍摄了内存消耗快照。它消耗了几乎所有部分的内存,但是,它不会失败。
它总是失败cat
命令。
我猜想,在反引号上,它会尝试分叉一个新进程,但该进程没有获得足够的内存,因此会失败。
请让我知道您的意见和替代方案。
因此,看来您的系统运行内存相当低,并且生成 shell + 调用 cat 对于剩余的少量内存来说太多了。
如果您不介意损失一些速度,您可以在 ruby 中合并文件,并使用较小的缓冲区。
这可以避免生成 shell,并且您可以控制缓冲区大小。
这是未经测试的,但你明白了:
buffer_size = 4096
output_file = File.open(final_output_file, 'w')
Dir["#{processing_directory}/*.csv"].sort_by {|file| [file.count("/"), file]}.each do |file|
f = File.open(file)
while buffer = f.read(buffer_size)
output_file.write(buffer)
end
f.close
end
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)