我知道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()调用之后,分配的内存应该被垃圾收集。为什么不这样做?
期待您的回复。
答案 0 :(得分:17)
根据How can I free an array or hash so my program shrinks?中的问题“perlfaq3”:
你通常不能。分配给词汇的内存(即my()变量) 即使超出范围也不能回收或重复使用。它是 保留以防变量返回范围。分配内存 通过使用可以重用(在程序中)全局变量 undef()和/或delete()。
在大多数操作系统上,分配给程序的内存永远不会 返回系统。这就是为什么长期运行的程序有时会重新 执行自己。一些操作系统(特别是使用的系统) mmap(2)用于分配大块内存)可以回收内存 不再使用,但在这样的系统上,必须配置perl 编译为使用操作系统的malloc,而不是perl的。
通常,内存分配和取消分配不是你的事 Perl可以或应该担心。
答案 1 :(得分:12)
Perl可能已将内存标记为已释放,但并不一定意味着它已freed back to the OS。您的Perl程序可能会重用该内存。尝试再次运行func
。您不应该看到使用的内存量增加。
您可能想要设置环境变量PERL_DESTRUCT_LEVEL
,看看是否有任何区别,但我对此表示怀疑。
Garbage collection不是Perl最大的优势之一。