我正在尝试在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>");
?>
答案 0 :(得分:4)
我会假设一旦我运行array_fill,它会在那时分配内存,并且它不应该在循环中耗尽内存。
是的......没有。分配内存和执行程序代码是两个不同的鞋子(通常) 分配给程序/进程的内存通常分为两堆 - 堆和堆栈。当您“分配内存”(在您的问题中使用的含义)时,这会发生在堆中。执行程序代码时,也会使用堆栈。两者都没有完全分开,因为您可以在堆栈上和/或堆栈中推送和/或弹出引用(指向堆的指针)。
问题是堆和堆栈共享内存的一部分(分配给该进程),并且通常从较高地址到低地址和从低地址到较高地址增长(正在填充)一,所以两者之间有一个“浮动”边界。一旦两个部分达到“边界”,你就会“失去记忆”
因此,在您的情况下,当您创建并填充数组(矩阵)时,您已使用2001 x 2001整数的内存。如果整数需要32位或4字节,那么有2001 x 2001 x 4字节= 4004001 x 4字节= 16016004字节~16 MB。
执行代码时,堆栈中充满了(本地)变量 - 循环条件变量,循环计数器和所有其他变量。
您也不应忘记PHP(库)代码也应该加载到内存中,因此根据您在配置中设置为memory_limit
的值,您可能会快速耗尽内存。