2015-10-11 2 views
0

Я написал код Perl, который обрабатывает файлы xml и создает массив из записей этого xml-файла. Когда массив большой, тогда я получил ошибку «Недостаточно памяти», пока я над ним, или использую «join» на нем.Как выпустить память в Perl?

Есть ли способ освободить память на Perl?

I get **$data** to the function: 

my @records =(); 
($records_section) = $data =~ /<gift-doc_body>(.+)<\/gift-doc_body>/ms; 

(@records) = $records_section =~ /<gift-doc_document>(.+?)<\/gift-doc_document>/msg; 

$new_xml = join("\n", "<root>", @records, "</root>"); 

я получил «из памяти» ошибка, когда он делает «Вступить»

+0

Возможно, вам не обязательно прочитать весь файл в памяти, но для получения реального ответа вам необходимо предоставить дополнительную информацию/соответствующие части вашего кода. – Nitek

+2

Для обработки XML-данных вы должны использовать правильный синтаксический анализатор XML. Если вы имеете дело с очень большим файлом, тогда вам нужно будет ['XML :: Twig'] (http://metacpan.org/module/XML::Twig), но вам придется объяснить, что вы пытаясь решить, прежде чем мы сможем помочь – Borodin

ответ

4

Первый - Perl не «бесплатно» память - она ​​имеет GC для этого. Во-вторых, когда вы читаете в память, лучше не читать все (как указано Nitek). Я предлагаю вам использовать XML :: Twig или XML :: XPath для чтения и анализа файла, поскольку он обрабатывает «большую» обработку данных для вас (в кусках).

4

Perl делает свою собственную сборку мусора. Вам не нужно беспокоиться о освобождении памяти - это автоматически, когда вы перестаете ее использовать.

Способ, которым вы «свободны», останавливаясь, ссылаясь на него. Поэтому, если вы держите прицелы настолько туго, насколько это возможно, вы не теряете память.

Однако XML является немного особый случай - проблема с XML является то, что а) это объем памяти примерно в 10 раз размер файла и б) имеет иметь совпавшие теги, а значит, вы можете в конечном итоге, для анализа всего файла, чтобы гарантировать соответствие тегов.

Возможно, это проблема, с которой вы столкнулись - большой XML-файл. Чтобы обрабатывать большой XML-файл, вы не можете прочитать все, что вам нужно, чтобы убедиться, что оно действительно.

Однако один раз из библиотек разбора - XML::Twig позволяет использовать обработчики для разбора подмножеств файла по мере его поступления. Вы должны это сделать. Посмотрите на purge, который будет освободить память, как вы идете:

#!/usr/bin/perl 

use strict; 
use warnings; 

use XML::Twig; 

sub process_some_element { 
    my ($twig, $some_element) = @_; 
    $some_element->print; 
    $twig->purge; 
} 

my $twig = 
    XML::Twig->new(
    twig_handlers => 
     { 'some_element' => \&process_some_element }); 
$twig->parsefile('sample.xml'); 

Важной частью здесь является purge - потому что он отбрасывает XML видел до сих пор. Вы также можете использовать flush, который делает то же самое, но печатает «увиденный» XML, если, например, вы хотите изменить и сохранить структуру документа.

Смежные вопросы