如何在Perl中释放内存

如何在Perl中释放内存,perl,memory,daemon,Perl,Memory,Daemon,我在perl上有带子进程的守护进程。对于daemonize,我使用Proc::Daemon。控制连接到DB(DBIlib)的守护进程和子进程,子进程也通过imap(mail::IMAPClientlib)收集邮件。Iundef儿童代码中的所有变量,但随着时间的推移,一个比任何人都工作的儿童会消耗大量内存ps输出: user 16521 0.6 1.6 135560 16516 ? S 10:47 0:54 perl remote_imap.pl user 16

我在perl上有带子进程的守护进程。对于daemonize,我使用
Proc::Daemon
。控制连接到DB(
DBI
lib)的守护进程和子进程,子进程也通过imap(
mail::IMAPClient
lib)收集邮件。I
undef
儿童代码中的所有变量,但随着时间的推移,一个比任何人都工作的儿童会消耗大量内存<代码>ps输出:

user   16521  0.6  1.6 135560 16516 ?        S    10:47   0:54 perl remote_imap.pl
user   16523  0.2 20.0 331976 201764 ?       S    10:47   0:21 perl remote_imapd.pl 16521
user   16525  0.1  3.0 157792 30720 ?        S    10:47   0:09 perl remote_imapd.pl 16521
user   16527  0.1  3.0 157796 30704 ?        S    10:47   0:08 perl remote_imapd.pl 16521
user   16529  0.1  3.0 157796 30572 ?        S    10:47   0:09 perl remote_imapd.pl 16521
user   16531  0.1  3.0 157792 30612 ?        S    10:47   0:08 perl remote_imapd.pl 16521
对于睡眠,我使用
usleep
from
Time::HiRes
lib。在remote\u imap.pl
usleep(100000)
中,在
remote\u imapd.pl
-
usleep(500000)

为什么不释放内存,因为我对所有变量都执行了
andef
(id\u连接到DB除外)?如果你愿意,我会添加代码

主守护进程 小孩
Perl使用引用计数来管理其内存空间。声明变量时,会留出一小部分。当您使用它时,会占用更多的内存。一旦变量不再被引用,Perl就可以重用内存空间

这就是为什么保持词法作用域很小并避免全局变量非常重要的原因——某些全局变量在整个代码中都“在作用域内”,即使它只使用了一次

这个问题是循环引用。循环引用永远不会成为未引用的引用,因此perl无法自动“释放”它。如果对象的一部分引用了对象的另一部分,那么也很容易得到内部对象

这就是为什么你会有这样的事情

我将在您上面给出的示例中注意到—子进程(为什么您将文件称为相同的东西?),您已经在词汇上确定了范围:

my (@array, @is_ok, @params, $user_id, $user_remote_id, $is_delete, $error_count, $is_first, $server, $port, $login, $password, $is_ssl, $no_error, $error_text, $pid, $date, $date_up, $exists, $q, $sth, $rv);
在你的
while
循环之外,试图通过以下方式“整理”:

(@array, @is_ok, @params, $user_id, $user_remote_id, $is_delete, $error_count, $is_first, $server, $port, $login, $password, $is_ssl, $no_error, $error_text, $pid, $date, $date_up, $exists, $q, $sth, $rv) = undef;

出于兴趣-你为什么这么做?你能不能不在while循环中定义它们,这样你就不需要重用它们了?但我不知道这一定是您的问题-它可能很容易位于您导入的某个库中。事实上,它发生在更繁忙的子循环中,这意味着每个循环都会有东西到达一个持久化的数组或对象

添加足够小的代码来重现问题。是的,首先需要查看代码以了解内存分配的位置。检查并。谢谢,现在我正在阅读。您还应该知道,将undef分配给数组与分配标量的工作方式不同@array=undef与undef(@array)的作用不同,我不记得在何处,但我读到最好在使用局部变量之前,先使用全局变量,并在期间的每个循环中执行and。但结果是一样的。如果需要,我可以使用Lib.pm添加您的所有代码。