简体   繁体   中英

Why does memory overflow when using array_map for big array?

When I'm testing array_map() function. There is a very strange phenomenon.

Normal size array

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

Result

8649024
8649024

It's obvious that the memory size is equal.

But for big array

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

Result

84319040

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 36 bytes) in G:\\phpStudy\\WWW\\testSpeed.php on line 6

Why? I have search answer everywhere. But it seems that there are few people have this problem. If anyone can help me? Thank you!

Maybe PHP's array_map() is internally copying the array to work with (84319040*2 > 134217728). You could raise the memory_limit (in php.ini, or specifically for this script using memory_limit(256*1024*1024) ), but I'd suggest you either use something like foreach($array as $key => &$value) { ... } - note the &$value here: you can modify the value directly, and PHP would not internally create a copy of the value. Also chances are good PHP runs it's garbage collector while the foreach() loop is active.

I have test it second time. I have found a interesting phenomenon. The code as follow: 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>'; 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>';

The output as follows: 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 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() applies call back function to each element in original array. so the function executes per each element in array and tries to allocate memory to result. when the limit of the memory usage(for executing function for each array element+ array elements) exceeds the memory allocated , this error occurs. In this example array map doesn`t have to do anything with memory exhaustion. It`s the range() function which throws error when it tries to allocate memory to the array which is trying to create

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM