php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #55033 Memory Leak in magic method __get() [Zend Memory Manager]
Submitted: 2011-06-11 14:40 UTC Modified: 2011-06-11 22:47 UTC
Votes:1
Avg. Score:4.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: rodney dot rehm at medialize dot de Assigned:
Status: Not a bug Package: Performance problem
PHP Version: 5.3.6 OS: Mac OS X 10.6.7
Private report: No CVE-ID: None
 [2011-06-11 14:40 UTC] 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

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2011-06-11 16:48 UTC] felipe@php.net
-Status: Open +Status: Bogus
 [2011-06-11 16:48 UTC] 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 17:01 UTC] 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 17:02 UTC] felipe@php.net
A copy of returned variable is done.
 [2011-06-11 17:42 UTC] 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 21:45 UTC] rodney dot rehm at medialize dot de
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.
 [2011-06-11 22:47 UTC] felipe@php.net
Hi, this behavior is some needs to be changed, I'm not ignoring your point, just closed the report since it has been already reported.

Thanks.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Mar 29 12:01:27 2024 UTC