PHP大数组的内存错误

6

我想在PHP中创建一个大小为2000x2000(400万条目)的二维数组。但是似乎我在这里用完了内存,但错误出现的方式使我感到困惑。

当我定义该数组并使用array_fill命令最初填充它,并将数组(矩阵)中的每个位置初始化为0时,没有问题。

然而,如果我尝试迭代数组并填充每个位置为0,则会用完内存。

我认为一旦我运行array_fill,它就在那一点上分配了内存,循环过程中不应该用完内存。

当然,这只是代码的简化版本。在我的实际应用程序中,我将使用X和Y坐标从另一个表查找值,处理它,然后将其存储在我的矩阵中。这些将是浮点值。

请问有人可以帮忙解释一下吗?我应该用其他方法吗?

谢谢!

<?php

// Set error reporting.
error_reporting(E_ALL); 
ini_set('display_errors', TRUE);
ini_set('display_startup_errors', TRUE);

// Define Matrix dimensions.
define("MATRIX_WIDTH", 2000+1);
define("MATRIX_HEIGHT", 2000+1);


// Setup array for matrix and initialize it.
$matrix = array_fill(0,MATRIX_HEIGHT,array_fill(0,MATRIX_WIDTH,0));

// Populate each matrix point with calculated value.
for($y_cood=0;$y_cood<MATRIX_HEIGHT;$y_cood++) {

    // Debugging statement to see where the script stops running.
    if( ($y_cood % 100) == 0 )  {print("Y=$y_cood<br>"); flush();}

    for($x_cood=0;$x_cood<MATRIX_WIDTH;$x_cood++) {
        $fill_value = 0;
        $matrix[$y_cood][$x_cood]=$fill_value;
    }
}

print("Matrix width: ".count($matrix)."<br>");
print("Matrix height: ".count($matrix[0])."<br>");

?>

尝试增加PHP内存大小 memory_limit = 128M; 脚本可消耗的最大内存量(128MB)。我个人不建议相信不稳定脚本行为所导致的结果。 - Mark Zucchini
谢谢。最终完成了。 - ankGT
1个回答

4
我认为一旦我运行array_fill,它就会在那个时候分配内存,并且不应该在循环中耗尽内存。
是的...也不是。分配内存和执行程序代码是两码事(通常)。分配给程序/进程的内存通常分为两部分-堆栈和堆。当您“分配内存”(在您问题中使用的含义)时,这发生在堆中。当您执行程序代码时,还使用了堆栈。两者并不完全分离,因为您可以将引用(指向堆的指针)推入或弹出堆栈。
问题是堆和堆栈共享部分内存(分配给该进程),通常一个从高地址向低地址增长(被填充),另一个从低地址向高地址增长,因此您在两者之间有一个“浮动”边界。一旦两个部分都达到了那个“边界”,您就“没有内存可用”。
因此,在您的情况下,当您创建和填充数组(矩阵)时,您已经使用了2001 x 2001个整数的内存。如果一个整数需要32位或4字节,则有2001 x 2001 x 4字节=4004001 x 4字节= 16016004字节〜16 MB。执行代码时,堆栈被(本地)变量填充-循环条件变量,循环计数器和所有其他变量。您还应该不要忘记PHP(库)代码也应加载到内存中,因此取决于您在配置中设置的memory_limit值,您可能会很快耗尽内存。

1
感谢您的解释! - ankGT

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接