为什么在释放大型数组时Perl不会垃圾收集内存?

时间:2013-01-04 14:44:45

标签: perl memory-management

我知道Perl使用基于引用计数的垃圾收集。 当变量超出范围时,引用计数递减,如果REFcount变为0,则取消分配内存。 但是当我追踪下面显示的一个小例子时,我无法找到解除分配的情况。

print "start..";

memory usage at start state

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

memory usage after allocation

}

func();

print "done..";

memory usage during garbage collection stage

在该示例中,当程序启动时,Perl.exe占用约3 MB的物理内存。 在func()调用期间分配后,Perl.exe占用~370 MB内存。 但是在func()调用之后,分配的内存应该被垃圾收集。为什么不这样做?

期待您的回复。

2 个答案:

答案 0 :(得分:17)

根据How can I free an array or hash so my program shrinks?中的问题“perlfaq3”:

  

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

     

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

     

通常,内存分配和取消分配不是你的事   Perl可以或应该担心。

     

另见How can I make my Perl program take less memory?

答案 1 :(得分:12)

Perl可能已将内存标记为已释放,但并不一定意味着它已freed back to the OS。您的Perl程序可能会重用该内存。尝试再次运行func。您不应该看到使用的内存量增加。

您可能想要设置环境变量PERL_DESTRUCT_LEVEL,看看是否有任何区别,但我对此表示怀疑。

Garbage collection不是Perl最大的优势之一。