Perl语言再学习(3): 垃圾回收
Perl的垃圾回收机制
之前一直没怎么关注过这个问题。 直到前两天线上出了个疑似内存泄漏的事情,让我去查一查,才解除了相关的一些知识。 归结起来大致如下:
Perl的垃圾回收机制是在每次从一个block里退出时被触发的,比如:
这个code block可能是一个子函数,一个循环,一个if-else分支,甚至可能只是如上边这样的代码块。
当perl退出这样的block的时候会回收在代码块内部定义的变量。
但是有一个特殊情况,如果变量的引用计数
不是0的话,则这个变量不会被回收。
于是就有了如下问题:
这样的代码由于$a
和$b
相互引用形成环,而使得两个变量都没有被释放。
上边这个例子更简单的版本是这样的:
当然,在程序退出的时候,Perl会采用一种mark-and-sweep的方法释放内存,可以彻底的释放掉所有使用的内存。
所以对于CGI程序来说,以适当的间隔重启可以有效防止内存泄漏吃光机器的内存。
另一个解决方法是使用弱引用WeakRef
。
CPAN上有这个模块,这样的引用不会影响引用计数。
不过我觉得只要注意一下,倒是不必须使用这样的模块。
检测内存泄漏的方法
尝试过几个库,LeakTrace.pm应该是最好用的一个。
下面是一个简单的例子:
当然,也有缺点,因为检测比较费时间,所以基本上线上跑这个比较困难。
这对于大型项目来说自然不是什么好消息。
不过好在这玩意开源,需要的话自己改吧~