Потребление памяти при использовании Nokogiri и XML - PullRequest
0 голосов
/ 17 апреля 2019

Я пытался выяснить, что случилось с моим приложением Rails, так как оно связано с памятью и парсингом Nokogiri XML. По какой-то причине одна эта функция потребляет около 1 ГБ памяти и не освобождает ее после завершения. Я не совсем уверен, что здесь происходит.

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 дает сбой при попытке проанализировать XML-файл размером более 100 МБ, я решил разбить XML-файлы на отдельные файлы, если их размер превышает 10 МБ, и просто пытаюсь обрабатывать их по отдельности.

Есть какие-нибудь мысли о том, почему это не освободит около 1 ГБ памяти, когда она будет заполнена?

1 Ответ

1 голос
/ 17 апреля 2019

Nokogiri использует системные библиотеки, такие как libxml и libxslt.Из-за этого я предположил бы, что это, вероятно, проблема не в сборке мусора в Ruby, а где-то еще.

Если вы работаете с большими файлами, обычно хорошей идеей является их потоковая обработка, чтобы вы этого не делали.загрузить весь файл в память, что само по себе приведет к огромному потреблению памяти, так как большие строки очень потребляют память.

Из-за этого при работе с большими файлами XML вы должны использовать анализатор потока.В Нокогири это Nokogiri::XML::SAX.

...