Bug #55033 [Com]: Memory Leak in magic method __get() [Zend Memory Manager]

From: Date: Sat, 11 Jun 2011 19:45:57 +0000
Subject: Bug #55033 [Com]: Memory Leak in magic method __get() [Zend Memory Manager]
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-161319@lists.php.net to get a copy of this message
Edit report at http://bugs.php.net/bug.php?id=55033&edit=1 ID: 55033 Comment by: rodney dot rehm at medialize dot de Reported by: rodney dot rehm at medialize dot de Summary: Memory Leak in magic method __get() [Zend Memory Manager] Status: Bogus Type: Bug Package: Performance problem Operating System: Mac OS X 10.6.7 PHP Version: 5.3.6 Block user comment: N Private report: N New Comment: Well, I figure since Bug #48197 is still open, the issue will be resolved eventually. If you're facing memory problems because of __get() you might want to sporadically clone the object: $object = clone $object; The wasted memory is not cloned. Beware that you are trading memory for runtime. Only consider this if you are facing memory issues or runtime is not an issue. Previous Comments: ------------------------------------------------------------------------ [2011-06-11 17:42:22] rodney dot rehm at medialize dot de Just to get this straight. This is not a bug, it's expected behavior. Anything returned from a magic method is internally handled as a copy. That means that anything a magic methods returns, even if it's a reference to another object, is kept in memory. That is, until the $object the magic methods were invoked on, is unset(). Are you kidding me? Not a bug? Where is this not a bug? A note on this topic wouldn't harm the docs, you know? ------------------------------------------------------------------------ [2011-06-11 17:02:32] felipe@php.net A copy of returned variable is done. ------------------------------------------------------------------------ [2011-06-11 17:01:14] rodney dot rehm at medialize dot de What exactly do you mean by "separating return from __get()"? The memory is pumped regardless of how I return (value, reference). How am I supposed to "separate" here? ------------------------------------------------------------------------ [2011-06-11 16:48:14] felipe@php.net There is no memleak, what happens is that the return from __get() needs to be separated. See bug #48197 ------------------------------------------------------------------------ [2011-06-11 14:40:52] rodney dot rehm at medialize dot de Description: ------------ For some reason values returned by __get() aren't released from memory. $ php memory.php # (without --debug) 0.0096 seconds and 1.3461 MB for 10000 accessing known property $ php memory.php # (with --debug) 0.0317 seconds and 2.6435 MB for 10000 accessing known property $ export USE_ZEND_ALLOC=0 $ php memory.php # (with --debug) 0.0267 seconds and 0.0000 MB for 10000 accessing known property since disabling Zend Memory Manager solved the issue, the valgrind log is pretty much useless, thus not attached. Test script: --------------- <?php class Memleak { public function __get($name) { return "hello world"; } } $iterations = 10000; $foo = new Memleak(); $start = microtime(true); $mem = memory_get_usage(); for ($i=0; $i < $iterations; $i++) { $foo->{'bar' . $i}; } $_mem = memory_get_usage(); $_start = microtime(true); printf("%0.4f seconds and %0.4f MB for %d accessing known property\n", $_start - $start, ($_mem - $mem) / 1024 / 1024, $iterations); ?> Expected result: ---------------- 0.0099 seconds and 0.0000 MB for 10000 accessing known property Actual result: -------------- 0.0099 seconds and 1.3460 MB for 10000 accessing known property ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/bug.php?id=55033&edit=1

« previous php.bugs (#161319) next »