On 11 March 2015 at 21:44, Dmitry Stogov <dmi...@zend.com> wrote: > Hi, > > Improvement ideas are welcome...
Hi Dmitry, The idea was raised before of having both soft and hard limits for the memory consumption and time limits, and to trigger a user defined callback when the soft limit was reached. This would be beneficial in a couple of ways. i) It allows people to detect that their application is consuming more memory/time than they would like, but not enough to cause stability issues. This would be useful in production where you don't want to make a request fail unless you absolutely have to. ii) It allows them to decide exactly what action to take. Sometimes it's fine to terminate requests straight away, other times people would want to do some cleanup before terminating. Additionally being able to call gc_collect_cycles() in the callback would sometimes release enough memory to bring the memory used to back under the soft limit and so allow processing to continue. Ironically, this seems to be an issue when writing efficient PHP code. Due to the way the garbage collector only collects cycles rarely, if you have very large variables compared to typical code, you can easily encounter a situation where the total memory that is still being referenced is small, but there is still a huge amount being held in cycles. The code below shows this happening: With gc_collect_cycles called: peak memory = 786kB Without gc_collect_cycles called: Allowed memory size of 67108864 bytes exhausted i.e. 95% of memory allocated isn't being used and could be freed, but hasn't because the number of GC objects didn't reach 10,000 and so the gc_collect_cycles didn't kick in automatically. cheers Dan <?php $performGC = false; if ($performGC) { echo "GC collection will be done - app should not crash.\n"; } else { echo "GC collection won't be done - app should crash.\n"; } $dataSizeInKB = 128; //Change this line if you tweak the parameters above. ini_set('memory_limit', "64M"); $memData = ''; for ($y=0 ; $y<$dataSizeInKB ; $y++) { for ($x=0 ; $x<32 ; $x++) { //1kB $memData .= md5(time() + (($y * 32) + $x)); } } file_put_contents("memdata.txt", $memData); // This function creates a cyclic variable loop function useSomeMemory($x) { $data = []; $data[$x] = file_get_contents("memdata.txt"); $data[$x + 1] = &$data; }; for($x=0 ; $x<1000 ; $x++) { useSomeMemory($x); if ($performGC == true) { gc_collect_cycles(); } } printf( "\nused: %10d | allocated: %10d | peak: %10d\n", memory_get_usage(), memory_get_usage(true), memory_get_peak_usage(true) ); -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php