Perl substr内存泄漏
您好我正在使用Perl变量中的大字符串数据(其原始电子邮件正文,因此它可以包含附件).与Perl的substr有趣的问题.似乎它的泄漏或我做错了什么(如果是,什么?).考虑代码:
#!/usr/local/bin/perl use strict; my $str = 'a'x10_000_000; system("ps up $$"); #22mb used (why?) #USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND #alt 64398 0,0 0,2 33292 22700 7 S+J 22:41 0:00,03 /usr/local/bin/perl ./t.pl substr($str,1)=''; system("ps up $$"); #No leak #USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND #alt 64398 0,2 33292 22732 7 S+J 22:41 0:00,04 /usr/local/bin/perl ./t.pl substr($str,500); system("ps up $$"); #Leaked 10Mb (why?!) #USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND #alt 64398 0,3 43532 32520 7 S+J 22:41 0:00,05 /usr/local/bin/perl ./t.pl my $a = substr($str,500); system("ps up $$"); #Leaked 10Mb + Copyed 10Mb #USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND #alt 64398 0,5 64012 52096 7 S+J 22:41 0:00,09 /usr/local/bin/perl ./t.pl undef $a; #Free scalar's memory system("ps up $$"); #Free'd 10Mb #USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND #alt 64398 0,4 53772 42308 7 S+J 22:41 0:00,09 /usr/local/bin/perl ./t.pl # Total leaked 2 times for 10Mb each 看看substr($str,500);命令.另外它的字符串的返回副本(没关系),它泄漏了相同数量的内存,所以如果你使用返回值它的两块内存,其中一个在整个时间脚本工作中丢失…而且,似乎它不是任何一种“内部缓冲区”,因为它泄漏了每个调用.. 注意这种10Mb增加的情况不是“重用”内存,因为后续调用会获得越来越多的内存. 有任何建议如何修复或避免? 我的Perl版本5.14.2;我的工作相同的行为(5.8.8) 解决方法
如果你在分配$str之前坚持使用ps检查,你会发现只有2兆用于运行perl.因此,分配$str需要20兆,是正在创建的字符串的两倍.如果我不得不猜测发生了什么,perl必须制作一个10兆字符串,然后将其复制到$str. 20兆.它保留在以后使用的分配内存.
substr($str,1)=”导致$str指向一个新的C字符串,你可以用Devel :: Peek看到它,但进程内存不会增加.它可能会使用释放的内存来为’a’x 10_000_000分配内存. 我的$a = substr($str,500);有一个类似的问题. substr创建一个新的10兆字符串,然后将其复制到需要20兆的$a.为什么需要更多的系统内存才能做到这一点我不确定.它可以从操作系统获得的前一个10兆字节块中分配内存,因此不再是单个10兆字节块,它不得不向操作系统询问更多内容. undef $a肯定会清除与$a关联的C字符串,你可以看到Devel :: Peek,但是perl不一定会将内存释放回操作系统. 无论如何,这是我最好的猜测. 简而言之,当一个进程将内存释放回操作系统时,操作系统很复杂,而操作系统则采用不同的方式.这是one discussion specifically about perl和one about Linux. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |