如何在Perl中释放内存 [英] How to free memory in the Perl

查看:177
本文介绍了如何在Perl中释放内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在perl上有一个带有孩子的守护进程.对于守护进程,我使用Proc::Daemon.控制守护程序和连接到DB(DBI lib)的子代,子代也通过imap(Mail::IMAPClient lib)收集邮件.我undef儿童代码中的所有变量,但是随着时间的流逝,一个比任何人都工作更多的孩子会占用大量内存. ps输出:

I have daemon with children on perl. For daemonize i use Proc::Daemon. Control daemon and children connected to DB(DBI lib), childs collect mail via imap (Mail::IMAPClient lib) too. I undef all variables in code of children, but over time, a child who works more than anyone, consume a lot of memory. ps output:

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

睡眠我使用Time::HiRes lib中的usleep.在remote_imap.pl usleep(100000)中,在remote_imapd.pl-usleep(500000)中.

for sleep i use usleep from Time::HiRes lib. In remote_imap.pl usleep(100000), In remote_imapd.pl - usleep(500000).

为什么不释放内存,因为我对所有变量(数据库的id_connet除外)都做了andef?如果您愿意,我会添加代码.

Why memory is not released, because I did andef for all variables (except id_connet to DB)? If you want, I'll add code.

主守护程序 remote_imap.pl 孩子 remote_imapd.pl

Main daemon remote_imap.pl Child remote_imapd.pl

推荐答案

Perl使用引用计数来管理其内存空间.声明变量时,会保留一小部分.使用它时,会占用更多的内存.一旦完全不再引用变量,Perl可能会重用内存空间.

Perl uses reference counting to manage it's memory space. When you declare a variable, a small amount is set aside. When you use it, more memory is occupied. Perl may reuse the memory space once a variable is no longer referenced at all.

这就是为什么保持词法作用域较小并避免全局变量非常重要的原因-全局变量在整个代码中都在范围内",即使仅使用一次也是如此.

That's why it's quite important to keep lexical scopes small, and avoid global variables - something global is 'in scope' throughout your code, even if it's only used once.

陷阱是循环引用.循环引用从不变为未引用,因此perl不能自动释放"它.如果对象的一部分引用了该对象的另一部分,那么以内部对象结束也很容易.

The gotcha is circular references. A circular reference never becomes unreferenced, so perl can't 'release' it automatically. That's also fairly easy to end up with inside objects - if part of an object has a reference to another part of the object.

这就是为什么您会有类似 weaken() 之类的东西的原因

That's why you have things like weaken().

在上面提供的示例中,我会指出-子进程(为什么将文件命名为同一东西?),您在词法上进行了范围界定:

I'll note in the examples you give above - the child process (why did you call the files the same thing?) you've lexically scoped:

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循环之外,并尝试通过以下方式整理":

Outside your while loop, and tried to 'tidy up' by:

(@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循环中定义它们的范围,然后就不需要重用它们了?我不知道这一定是您的问题-可能很容易在您导入的库之一中.它与忙碌的孩子一起发生的事实意味着,每个循环都将某事物循环到持久存在的数组或对象.

Out of interest - why are you doing this? Could you not scope them within your while loop, and then you won't need to reuse them? I don't know that's necessarily your problem though - it could quite easily be in one of the libraries you import. The fact that it's happening with the busier child implies that each loop something is getting to an array or object that's persisting.

这篇关于如何在Perl中释放内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆