Why does memory overflow when using array_map for big array?
Asked Answered
S

3

6

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!

Sven answered 28/12, 2017 at 7:24 Comment(4)
set your memory limit to -1 in php.ini. though it is not a good approach but this will workZobkiw
Iy is better too diivide in severa arrays. That one is way too big.Infanta
Thanks for your answer. The point I am curious it's that when use big size array the memory would doule, but not in small size array.Sven
The memory usage also doubles with the small array, but is freed when array_map() is done. If you'd increase the memory_limit, you'd get two similar numbers in your second example tooEarmuff
S
0

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

Sverige answered 28/12, 2017 at 9:40 Comment(0)
S
2

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>';

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 array_map finish, the memory size is back before the array_map starts 
126417184
Sven answered 28/12, 2017 at 9:22 Comment(0)
E
1

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.

Earmuff answered 28/12, 2017 at 8:1 Comment(1)
Hi. As you're new: We don't really post "I'm guessing that..." posts. You might have a good answer, but do some research and/or add some documentation/research by someone else so that we can verify your answers, instead of guessing it might work :)Raptorial
S
0

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

Sverige answered 28/12, 2017 at 9:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.