I have a server which has 2 PHP scripts that run continuously in the background. One of those scripts, for some reason, is not releasing memory and it’s making the other script fail because eventually I have no available RAM left on the server.
I created a pretty simple POC so you can check by yourself. Basically I have a function that checks the available RAM memory (using free command) three times, and after the first time I execute the function that makes memory be consumed and never released. I even tried gc_collect_cycles but nothing happens.
What amazes me, is that after the script finishes completely, if I go to my SSH and execute “free” all the used memory is indeed released however if I add a long sleep at the end o my script, the memory will keep being used. Notice that inside the function test() a local variable is created and it is explicitly unsetted, but for some reason PHP still holds the memory.
<?php
set_time_limit(0);
ini_set("memory_limit","-1");
function show_available_ram() {
$temp1111 = shell_exec('sudo free -m');
preg_match("/Mem: +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +([0-9]+)/",$temp1111,$temp2222);
return $temp2222[1] . " MB";
}
function test() {
$temp3333 = array();
for ($i=0;$i<1000000;$i++) {
$temp3333[] = array("key1" => md5($i), "key2" => $i);
}
unset($temp3333);
}
echo "nAAA: " . show_available_ram();
test();
sleep(2);
echo "nBBB: " . show_available_ram();
//I know it should not be needed the line below, but I am trying it anyway but it does not help.
gc_collect_cycles();
sleep(2);
echo "nCCC: " . show_available_ram();
?>
The code above outputs:
AAA: 1297 MB
BBB: 873 MB
CCC: 869 MB
So you can clearly see memory being used (on BBB and CCC but not released even after test() has already finished.
In the code above I use a few sleep so PHP can have time to garbage collect, but it does not help at all.