我一直在尝试弄清我的Rails应用程序的最新情况,因为它与内存和Nokogiri的XML解析有关。由于某种原因,仅此一项功能就会消耗大约1GB的内存,并且在完成时不会释放它。我不太确定这是怎么回事。
def split_nessus
# To avoid consuming too much memory, we're going to split the Nessus file
# if it's over 10MB into multiple smaller files.
file_size = File.size(@nessus_files[0]).to_f / 2**20
files = []
if file_size >= 10
file_num = 1
d = File.open(@nessus_files[0])
content = Nokogiri::XML(d.read)
d.close
data = Nokogiri::XML("<data></data>")
hosts_num = 1
content.xpath("//ReportHost").each do |report_host|
data.root << report_host
hosts_num += 1
if hosts_num == 100
File.open("#{@nessus_files[0]}_nxtmp_#{file_num}", "w") {|f| f.write(data.to_xml)}
files << "#{@nessus_files[0]}_nxtmp_#{file_num}"
data = Nokogiri::XML("<data></data>")
hosts_num = 1
file_num += 1
end
end
@nessus_files = files
end
end
由于Rails在尝试解析100MB以上的XML文件时崩溃,因此,我决定将超过10MB的XML文件分解为单独的文件,并尝试单独处理。
有人想知道为什么它在完成后不会释放大约1GB的内存吗?
答案 0 :(得分:1)
Nokogiri在后台使用libxml
和libxslt
之类的系统库。因此,我认为这可能不是Ruby垃圾回收中的问题,而是其他地方。
如果使用大文件,通常对它们进行流处理是个好主意,这样就不会将整个文件加载到内存中,这本身会导致巨大的内存消耗,因为大字符串非常占用内存
因此,在处理大型XML文件时,应使用流解析器。在Nokogiri中,这是Nokogiri::XML::SAX
。