加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Perl substr内存泄漏

发布时间:2020-12-15 21:45:38 所属栏目:大数据 来源:网络整理
导读:您好我正在使用Perl变量中的大字符串数据(其原始电子邮件正文,因此它可以包含附件).与Perl的substr有趣的问题.似乎它的泄漏或我做错了什么(如果是,什么?).考虑代码: #!/usr/local/bin/perluse strict;my $str = 'a'x10_000_000;system("ps up $$"); #22mb
您好我正在使用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.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读