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!

Philip
  • 3,689
  • 3
  • 24
  • 35
Tom Tao
  • 97
  • 7
  • set your memory limit to -1 in php.ini. though it is not a good approach but this will work – baig772 Dec 28 '17 at 07:31
  • Iy is better too diivide in severa arrays. That one is way too big. – halojoy Dec 28 '17 at 07:32
  • 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. – Tom Tao Dec 28 '17 at 07:41
  • 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 too – Thomas L. Dec 28 '17 at 08:04

3 Answers3

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
SEYED BABAK ASHRAFI
  • 4,093
  • 4
  • 22
  • 32
Tom Tao
  • 97
  • 7
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.

Thomas L.
  • 104
  • 8
  • 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 :) – Martijn Dec 28 '17 at 08:06
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

User123456
  • 2,492
  • 3
  • 30
  • 44