为什么大数组使用array_map会内存溢出?
Why does memory overflow when using array_map for big array?
当我测试 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
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried
to allocate 36 bytes) in G:\phpStudy\WWW\testSpeed.php on line 6
为什么?我到处都有搜索答案。但是好像很少有人有这个问题。
如果有人可以帮助我?谢谢!
也许 PHP 的 array_map()
正在内部复制要使用的数组 (84319040*2 > 134217728)。
您可以提高 memory_limit(在 php.ini 中,或者专门针对此脚本使用 memory_limit(256*1024*1024)
),但我建议您使用
foreach($array as $key => &$value) {
...
}
之类的东西 - 请注意 &$value
这里:可以直接修改值,PHP不会在内部创建值的副本。
当 foreach()
循环处于活动状态时,PHP 也很有可能运行它的垃圾收集器。
第二次测试了。我发现了一个有趣的现象。代码如下:
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
array_map()
将回调函数应用于原始数组中的每个元素。因此该函数针对数组中的每个元素执行并尝试为结果分配内存。当内存使用限制(为每个数组元素+数组元素执行函数)超过分配的内存时,会发生此错误。
在此示例中,数组映射不必对内存耗尽做任何事情。它是 range()
函数,当它试图将内存分配给试图创建
的数组时抛出错误
当我测试 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
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 36 bytes) in G:\phpStudy\WWW\testSpeed.php on line 6
为什么?我到处都有搜索答案。但是好像很少有人有这个问题。 如果有人可以帮助我?谢谢!
也许 PHP 的 array_map()
正在内部复制要使用的数组 (84319040*2 > 134217728)。
您可以提高 memory_limit(在 php.ini 中,或者专门针对此脚本使用 memory_limit(256*1024*1024)
),但我建议您使用
foreach($array as $key => &$value) {
...
}
之类的东西 - 请注意 &$value
这里:可以直接修改值,PHP不会在内部创建值的副本。
当 foreach()
循环处于活动状态时,PHP 也很有可能运行它的垃圾收集器。
第二次测试了。我发现了一个有趣的现象。代码如下:
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
array_map()
将回调函数应用于原始数组中的每个元素。因此该函数针对数组中的每个元素执行并尝试为结果分配内存。当内存使用限制(为每个数组元素+数组元素执行函数)超过分配的内存时,会发生此错误。
在此示例中,数组映射不必对内存耗尽做任何事情。它是 range()
函数,当它试图将内存分配给试图创建