【发布时间】:2016-09-15 14:10:37
【问题描述】:
我有一个应用程序,它可以将大量文本数据读入一个标量,有时甚至是 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 GB,我提取 4.9 GB 的数据并替换提取的数据。第二行现在将报告例如100 MB 的数据作为字符串的长度,但例如Devel::Size::total_size 仍会输出为该标量分配的 5 GB 数据。并且将undef 或诸如此类分配给$$contentRef 似乎并没有改变这一点,我需要在该标量上调用undef 作为函数。
我原以为$$contentRef 后面的内存在应用substr 之后已经至少部分释放了。好像不是这样的……
那么,只有在变量超出范围时才释放内存吗?如果是这样,为什么分配 undef 与调用 undef 作为同一标量上的函数不同?
【问题讨论】:
-
您是否在其他地方需要该内存?
-
是的,由于不同的原因,我有多个数据副本,此外,整个过程可能会并行执行。所以在整个过程中浪费了一些 GB 的内存是我需要关心的。是的,可能是糟糕的设计,但目前就是这样......
标签: perl memory memory-management