Ati*_*ith 14 ruby shell fork out-of-memory spawn
我有一个正在运行的工作,它处理xml文件.xml文件大约为4k,大小为8到9 GB.
处理完毕后,我们将CSV文件作为输出.我有一个cat命令,它将所有CSV文件合并到我得到的单个文件中:
Errno :: ENOMEM:无法分配内存
on cat(Backtick)命令.
以下是一些细节:
使用nokogiri和处理文件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}`
}
Run Code Online (Sandbox Code Playgroud)
我在处理期间拍摄了内存消耗快照.它几乎占用了内存的所有部分,但是,它不会失败.总是失败的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
Run Code Online (Sandbox Code Playgroud)