大数组的PHP内存错误

时间:2014-11-18 07:47:04

标签: php arrays out-of-memory

我正在尝试在PHP中创建一个大小为2000x2000(400万个条目)的2D数组。似乎我的内存耗尽,但出现错误的方式令我感到困惑。

当我定义数组并最初使用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>");

?>

1 个答案:

答案 0 :(得分:4)

  

我会假设一旦我运行array_fill,它会在那时分配内存,并且它不应该在循环中耗尽内存。

是的......没有。分配内存和执行程序代码是两个不同的鞋子(通常) 分配给程序/进程的内存通常分为两堆 - 堆和堆栈。当您“分配内存”(在您的问题中使用的含义)时,这会发生在堆中。执行程序代码时,也会使用堆栈。两者都没有完全分开,因为您可以在堆栈上和/或堆栈中推送和/或弹出引用(指向堆的指针)。

问题是堆和堆栈共享内存的一部分(分配给该进程),并且通常从较高地址到低地址和从低地址到较高地址增长(正在填充)一,所以两者之间有一个“浮动”边界。一旦两个部分达到“边界”,你就会“失去记忆” enter image description here

因此,在您的情况下,当您创建并填充数组(矩阵)时,您已使用2001 x 2001整数的内存。如果整数需要32位或4字节,那么有2001 x 2001 x 4字节= 4004001 x 4字节= 16016004字节~16 MB。
执行代码时,堆栈中充满了(本地)变量 - 循环条件变量,循环计数器和所有其他变量。
您也不应忘记PHP(库)代码也应该加载到内存中,因此根据您在配置中设置为memory_limit的值,您可能会快速耗尽内存。