У меня есть приложение, которое читает гигантский кусок текстовых данных в скаляр, иногда даже в формате GB. Я использую substr
на этом скаляре, чтобы прочитать большую часть данных в другом скаляре и заменить извлеченные данные пустой строкой, потому что это больше не нужно в первом скаляре. Недавно я обнаружил, что Perl не освобождает память первого скаляра, в то время как он распознает, что его логическая длина изменилась. Итак, что мне нужно сделать, это снова извлечь данные из первого скаляра в третий, undef
первый скаляр и вернуть извлеченные данные на место. Только так память, занятая первым скаляром, действительно освобождается. Присваивание undef этому скаляру или другому значению, меньшему, чем выделенный блок памяти, ничего не меняет в распределенной памяти.
Теперь я делаю следующее:
$$extFileBufferRef = substr($$contentRef, $offset, $length, '');
$length = length($$contentRef);
my $content = substr($$contentRef, 0, $length);
$$contentRef = undef( $$contentRef) || $content;
$$contentRef
может быть, например, 5 ГБ в первой строке, я извлекаю 4,9 ГБ данных и заменяю извлеченные данные. Вторая строка будет теперь отчитываться, например. 100 МБ данных как длина строки, но, например, Devel::Size::total_size
все равно выдаст, что для этого скаляра выделено 5 ГБ данных. И присваивание undef
или такому $$contentRef
, похоже, ничего не меняет, мне нужно вызвать undef
как функцию на этом скаляре.
Я бы предположил, что память за $$contentRef
уже по крайней мере частично освобождена после применения substr
. Кажется, не так...
Итак, освобождается ли память, если переменные выходят за рамки? И если да, то почему присвоение undef
отличается от вызова undef
как функции на том же скаляре?