I have an app which reads a giant chunk of textual data into a scalar, sometimes even GBs in size. I use substr
on that scalar to read most of the data into another scalar and replace the extracted data with an empty string, because it is not needed in the first scalar anymore. What I've found recently was that Perl is not freeing the memory of the first scalar, while it is recognizing that its logical length has changed. So what I need to do is extract the data from the first scalar into a third again, undef
the first scalar und put the extracted data back in place. Only this way the memory occupied by the first scalar is really freed up. Assigning undef to that scalar or some other value less than the allocated block of memory doesn't change anything about the allocated memory.
The following is what I do now:
$$extFileBufferRef = substr($$contentRef, $offset, $length, '');
$length = length($$contentRef);
my $content = substr($$contentRef, 0, $length);
$$contentRef = undef( $$contentRef) || $content;
$$contentRef
might be e.g. 5 GBs in size in the first line, I extract 4,9 GB of data and replace the extracted data. The second line would now report e.g. 100 MBs of data as the length of the string, but e.g. Devel::Size::total_size
would still output that 5 GB of data are allocated for that scalar. And assigning undef
or such to $$contentRef
doesn't seem to change a thing about that, I need to call undef
as a function on that scalar.
I would have expected that the memory behind $$contentRef
is already at least partially freed after substr
was applied. Doesn't seem to be the case...
So, is memory only freed if variables go out of scope? And if so, why is assigning undef
different to calling undef
as a function on the same scalar?