Perl:在运行时构建二维数组时出现内存不足错误

tir*_*esh 2 perl binaryfiles out-of-memory dynamic-arrays perl-data-structures

我是初学者.我试图在运行时从二进制文件构建一个2d数组.我收到了"内存不足"的错误.我在windows7中使用Perl 5.16.3.我的输入文件大小约为4.2MB.我的系统具有4GB的物理内存,我使用90%的使用率,然后在运行此代码时显示内存不足错误.

我尝试了很多方法来调试它.只有当我将b32减少到b16或更低时,我才能成功运行.即使这样,如果文件大小增加超过4MB,则错误再次出现.我尝试在执行代码时查看任务管理器中的物理内存使用情况,并且不断增加.

我的朋友怀疑这应该是内存泄漏问题.我无法与他的嫌犯弄清楚.我需要帮助解决这个问题.

#!/usr/bin/perl
use strict;
use warnings;

open( DATA, 'debug.bin' ) or die "Unable to open:$!";
binmode DATA;
my ( $data, $n, $i );
my @2dmatrix;
while ( $n = read DATA, $data, 4 ) {
    push @2dmatrix, [ split( '', unpack( 'b32', $data ) ) ];
}
print scalar(@2dmatrix);
print "completed reading";
close(DATA);
Run Code Online (Sandbox Code Playgroud)

只是为了明确要求.从2d数组构建中,我需要从列B中的特定模式(11111111000000001111111100000000)对应的列A中提取内容.这需要在文件大小为500Mb的4组列上完成.

hob*_*bbs 6

这不是内存泄漏,你的程序使用内存效率非常低.

对于您读入的每4个字节,您执行一个unpack 'b32'创建32个字符的字符串; split //它,它将它变成32个1个字符的字符串,生成结果列表的arrayref,然后按下arrayref @2dmatrix.这导致:

  • 32个字符串体,每个至少2个字节(用于"0\0"或者"1\0"),但是如果字符串增长,perl可能决定使用更多来避免重新分配:64字节.
  • 32个SVPV(包含字符串的标量变量,32位各28个字节,64位各40个字节):896或1280个字节.
  • 1个数组体,32个条目:32位128字节,64位256字节.
  • 1 AV(数组变量):32位28字节,64位40字节.
  • 1 SVRV(包含引用的标量):32位16字节,64位24字节.
  • @2dmatrix数组体中有1个条目:32位为4个字节,64位为8个字节.

结果是32位上每4字节1136字节(284x乘法)和64位上每4字节1672字节(418x乘法),不考虑常数因素和perl可能选择使用更大字符串体的事实(在我测试的两个perl版本上,我得到了10或16个字节,而不是2个.)因此,你的程序将使用超过1.1GB的内存,在32位系统上输入4.2MB,超过1.7GB在64位系统上输入4.2MB的内存.

这里的解决方案是存储和更有效的方式访问数据,但我不能给任何具体的建议,因为你还没说你实际上试图@2dmatrix,一旦你拥有了它.