php 为什么在使用array_map处理大数组时会出现内存溢出?

ncecgwcz  于 2022-12-17  发布在  PHP
关注(0)|答案(3)|浏览(193)

当我在测试array_map()函数的时候。有一个很奇怪的现象。

正常大小数组

$array = range(1, 100000);
echo memory_get_usage();
array_map(function($value) {}, $array);
echo memory_get_usage();

结果

8649024
8649024

很明显,内存大小是相等的。

但对于大数组

$array = range(1, 10000000);
echo memory_get_usage();
array_map(function($value) {}, $array);
echo memory_get_usage();

结果

84319040

致命错误:第6行的G:\phpStudy\WWW\testSpeed.php中允许的134217728字节内存大小已耗尽(尝试分配36字节)
为什么?我到处都有答案。但是好像很少有人有这个问题。如果有人能帮助我?谢谢!

wqsoz72f

wqsoz72f1#

我已经测试了第二次,我发现了一个有趣的现象.代码如下:

echo memory_get_usage() . '<br>';
$a = [
    range(1, 500000),
    range(1, 500000),
    range(1, 500000),
];
echo memory_get_usage() . '<br>';
array_map(function ($value) {
    echo memory_get_usage() . '<br>';
}, $a);
echo memory_get_usage() . '<br>';

输出如下:

124976
126417184
// $TheSizeOfEachElement = (126417224 - 125032) / 3 = 42097397.3333;
// When I am use array_map. The memory is add, but not equal the size of each element.
126417856
126417976
126418056
// When array_map finish, the memory size is back before the array_map starts 
126417184
yizd12fk

yizd12fk2#

也许PHP的array_map()正在内部复制数组(84319040*2〉134217728),您可以提高memory_limit(在php.ini中,或者专门针对使用memory_limit(256*1024*1024)的脚本),但我建议您使用类似foreach($array as $key => &$value) { ... }的代码-注意这里的&$value:你可以直接修改这个值,PHP不会在内部创建一个值的副本。当foreach()循环处于活动状态时,PHP运行垃圾收集器也是很有可能的。

gcmastyq

gcmastyq3#

array_map()将回调函数应用于原始数组中的每个元素。因此,该函数针对数组中的每个元素执行,并尝试将内存分配给结果。当内存使用限制(用于执行每个数组元素+数组元素的函数)超过分配的内存,这个错误发生了。在这个例子中数组Map不需要做任何内存耗尽的事情。它这是range()函数,当它尝试为试图创建的数组分配内存时,会抛出错误

相关问题