15

我知道 Perl 使用基于引用计数的垃圾收集。当变量超出范围时,引用计数减少,如果 REFcount 变为 0,则内存被释放。但是当我跟踪一个如下所示的小示例时,我无法找到正在发生的取消分配。

print "start..";

启动状态下的内存使用情况

sub func
{
    my $length = 8*1024*1024;
    my $array = [1..$length];

分配后的内存使用

}

func();

print "done..";

垃圾收集阶段的内存使用情况

在这个例子中,当程序启动时,Perl.exe 占用了大约 3 MB 的物理内存。在 func() 调用期间分配后,Perl.exe 占用约 370 MB 内存。但是在 func() 调用之后,分配的内存应该被垃圾回收。为什么没有完成?

期待您的回复。

4

2 回答 2

19

根据perlfaq3中的问题“如何释放数组或哈希以使我的程序缩小? ” :

你通常不能。分配给词法(即 my() 变量)的内存即使超出范围也无法回收或重用。它被保留以防变量返回范围。分配给全局变量的内存可以通过使用 undef() 和/或 delete() 重用(在您的程序中)。

在大多数操作系统上,分配给程序的内存永远不会归还给系统。这就是为什么长时间运行的程序有时会重新执行自己的原因。一些操作系统(特别是使用 mmap(2) 分配大块内存的系统)可以回收不再使用的内存,但在此类系统上,必须配置和编译 perl 以使用操作系统的 malloc,而不是 perl。

一般来说,内存分配和解除分配在 Perl 中不是您可以或不应该过多担心的事情。

另请参阅如何使我的 Perl 程序占用更少的内存?

于 2013-01-04T14:54:30.097 回答
13

Perl 可能已将内存标记为已释放,但这并不一定意味着它已被释放回操作系统。您的 Perl 程序可能会重用该内存。再次尝试运行func。您不应该看到使用的内存量增加。

您可能想设置环境变量PERL_DESTRUCT_LEVEL,看看是否有什么不同,但我对此表示怀疑。

垃圾收集不是 Perl 的最大优势之一。

于 2013-01-04T15:02:44.187 回答