Для начала - это не мой код - возникла проблема с кодом, и я пытаюсь выяснить, как отладить проблему.Я бы внес множество изменений в код, если бы мне дали такую возможность (чрезмерные скобки, глобальные переменные, использование функции соединения вместо foreach и т. Д. И т. Д. И т. Д.).Он полон плохой практики, но это не то, что мне нужно для помощи.
Вот фрагмент кода Perl (Нет подпрограмм, ничего особенного - в основном откройте файл для результатов запросавыполнить запрос и вывести результаты в файл):
# earlier in the program, @row, $field, and $output are all declared globally, like this:
my @row;
my $field;
my $output;
# a file is opened for output, with filehandle ROWOUT
# a database statement handle (DBD::DB2) is executed
while ( @{row} = ${sth}->fetchrow_array ) {
foreach ${field}( @{row} ) {
${field} =~ s/\s+$//;
${output} = "${output}\~${field}";
}
${output} =~ s/\~//;
print ROWOUT "${output}\n";
undef ${output};
}
Где-то в цикле while скрипт Perl падает с ошибкой Out of Memory!
(не чистый сбой - он просто перестает работатьс этим сообщением.)
В большинстве случаев объем этого запроса очень мал.Результаты запроса на этот раз, когда произошел сбой скрипта, намного больше (все еще не огромны): 150 000 строк, а каждая строка имеет ширину около 1200 байт.
Вещи, о которых я думал:
- Функция fetchrow_array в DBI достаточно умна, чтобы не вытягивать полный набор данных в память, верно?Я предполагаю, что данные находятся в базе данных, и fetchrow_array извлекает одну строку за раз, так что даже если у вас есть 10 миллиардов строк, у вас не должно быть проблем с памятью - это правильно?
- Вызов
undef
в переменной $output
освободит используемую память, правильно?Если это не так, это может быть другое место, где может существовать проблема с памятью. - Память, используемая переменной
@row
, будет повторно использоваться (?) Каждый раз при получении новой строки, правильно?Если нет, я мог бы увидеть, как использование глобального массива для хранения каждой строки может уничтожить память.
Я надеюсь, что есть нечто очевидное, чего я просто не понимаю.Если при просмотре кода нет ничего очевидного, какие методы я могу использовать для устранения этой проблемы?
Заранее спасибо!