使用Nokogiri和XML时的内存消耗

时间:2019-04-17 12:43:35

标签: ruby-on-rails nokogiri

我一直在尝试弄清我的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的内存吗?

1 个答案:

答案 0 :(得分:1)

Nokogiri在后台使用libxmllibxslt之类的系统库。因此,我认为这可能不是Ru​​by垃圾回收中的问题,而是其他地方。

如果使用大文件,通常对它们进行流处理是个好主意,这样就不会将整个文件加载到内存中,这本身会导致巨大的内存消耗,因为大字符串非常占用内存

因此,在处理大型XML文件时,应使用流解析器。在Nokogiri中,这是Nokogiri::XML::SAX