Ank*_*ikh 5 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>");
?>
Run Code Online (Sandbox Code Playgroud)
我假设一旦我运行 array_fill 它就会在此时分配内存,并且它不应该在循环中耗尽内存。
是的……也不是。分配内存和执行程序代码是两件不同的事情(通常)。
分配给程序/进程的内存通常分为两部分:堆和堆栈。当您“分配内存”(按照您在问题中使用的含义)时,这会发生在堆中。当您执行程序代码时,也会使用堆栈。两者并没有完全分开,因为您可以将引用(指向堆的指针)压入堆栈和/或从堆栈中弹出。
问题是,堆和堆栈共享部分内存(分配给该进程),通常一个从较高地址增长到低地址,另一个从低地址增长到较高地址,并且所以两者之间有一个“浮动”边界。一旦这两个部分都到达该“边界”,您就“内存不足”。

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