Q:

PHP free memory after unset

Its small code for test:
$strings = array('<big string here (2 Mb)');
$arr = array();

//--> memory usage here is 17.1Mb (checked by pmap)
echo memory_get_usage();//0.5Mb 
//(i know, that other 16.6Mb of memory used by process are php libraries)

for($i = 0; $i < 20; ++$i)
{
    $strings_local = array_merge($strings, array($i));
    $arr[$i] = $strings_local;
    unset($strings_local);
}

//--> memory usage here is 20.3Mb (checked by pmap)
echo memory_get_usage();//3.7Mb
//so, here its all ok, 17.1+3.2 = 20.3Mb

for($i = 0; $i < 20; ++$i)
{
    unset($arr[$i]);
}

//--> memory usage here is 20.3Mb (checked by pmap)
//BUT?? i UNSET this variables...
echo memory_get_usage();//0.5Mb

So, seems like php is not free memory, even if you unset() your variable. How can i free memory after unset?

A:

PHP has garbage collector which takes care of the memory management for you, which affects to memory usage (of the process) in several different ways.
First, when inspecting memory usage of a process outside of the process, even if PHP sees some memory to be freed, it may not be released back to the OS for optimization purposes related to memory allocation. This is reduce overhead from continuous frees and allocs, that happen more easily with GC’d languages, as allocation procedure is not visible to the actual program.
For that reason, even if one calls gc_collect_cycles() by hand, the memory may not be freed to the OS at all, but rather reused for future allocations. This causes PHP to see smaller memory usage than the process in reality uses, due to some early big reservation which never gets to freed back to the OS.
Second, due to nature of garbage collection, the memory may not be immediately freed after marked unused by the program. Calling gc_collect_cycles() will make the memory freed immediately, but it should be seen unnecessary, and does not work if you have logical (or something in PHP leaks) memory leak in your script.
For knowing what is going on, doing line by line inspection (for example with Xdebug’s function trace) would give you better insight about how PHP (or rather, your program) sees the memory usage.
Combining that to line-by-line inspection from outside of the process (for example your pmap commands) would tell if the PHP actually is freeing any memory at any point after reserving it. 

