php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #71818 Memory leak when array altered in destructor
Submitted: 2016-03-14 07:40 UTC Modified: 2017-10-24 05:20 UTC
Votes:2
Avg. Score:4.0 ± 1.0
Reproduced:2 of 2 (100.0%)
Same Version:1 (50.0%)
Same OS:0 (0.0%)
From: james dot harris at icecave dot com dot au Assigned: laruence (profile)
Status: Assigned Package: Scripting Engine problem
PHP Version: 7.0.4 OS: OSX
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2016-03-14 07:40 UTC] james dot harris at icecave dot com dot au
Description:
------------
A memory leak occurs when array that contains a reference to $this is altered in the object's destructor.

The leak does not occur if:
 * the array does not contain $this
 * the array is not altered in the destructor
 * $this is removed from the array in the destructor

Affected PHP versions: https://3v4l.org/lHeRV
This gist (https://gist.github.com/jmalloc/b88752e391d464609339) also contains the script to reproduce.




Test script:
---------------
class MemoryLeak
{
    public function __construct()
    {
        $this->things[] = $this;
    }

    public function __destruct()
    {
        $this->things[] = null;
    }

    private $things = [];
}

ini_set('memory_limit', '10M');

for ($i = 0; $i < 100000; ++$i) {
    $obj = new MemoryLeak();
}

echo "Done";

Expected result:
----------------
Done

Actual result:
--------------
Fatal error: Allowed memory size of 10485760 bytes exhausted (tried to allocate 20480 bytes) in /Users/james/<snip>/leak.php on line 30

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-04-14 14:35 UTC] jhdxr@php.net
-Status: Open +Status: Feedback
 [2016-04-14 14:35 UTC] jhdxr@php.net
"$this is removed from the array in the destructor"
In fact, you did NOT removed $thif from the array. `$this->things[] = null;` add a new element into the array. 

You can use
`$this->things = null;`
or
`unset($this->things);
 [2016-04-15 01:39 UTC] james dot harris at icecave dot com dot au
-Status: Feedback +Status: Open
 [2016-04-15 01:39 UTC] james dot harris at icecave dot com dot au
Those are the conditions under which the leak does NOT occur. Sorry, I worded it a bit backwards.

I realise this is a bit academic and strange, and I've certainly worked around whatever code I found doing this (I can't remember what it was now), but I figured it was still worth bring up incase it was an issue with the array implementation itself.

Thanks,
James
 [2016-07-14 09:05 UTC] dmitry@php.net
Automatic comment on behalf of dmitry@zend.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=8fc934b0a1781bc0685775f4c476c6704d796a76
Log: Fixed bug #71818 (Memory leak when array altered in destructor)
 [2016-07-14 09:05 UTC] dmitry@php.net
-Status: Open +Status: Closed
 [2016-07-14 09:08 UTC] dmitry@php.net
-Status: Closed +Status: Assigned -Assigned To: +Assigned To: laruence
 [2016-07-14 09:08 UTC] dmitry@php.net
Fixed in PHP-7.1.
http://git.php.net/?p=php-src.git;a=commitdiff;h=8fc934b0a1781bc0685775f4c476c6704d796a76
The patch might be backported to PHP-7.0 after additional testing.
 [2016-07-20 11:29 UTC] davey@php.net
Automatic comment on behalf of dmitry@zend.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=8fc934b0a1781bc0685775f4c476c6704d796a76
Log: Fixed bug #71818 (Memory leak when array altered in destructor)
 [2016-07-20 11:29 UTC] davey@php.net
-Status: Assigned +Status: Closed
 [2016-07-21 07:23 UTC] davey@php.net
-Status: Closed +Status: Assigned
 [2016-07-21 07:23 UTC] davey@php.net
Closed accidentally. Reopening.
 [2016-10-17 10:11 UTC] bwoebi@php.net
Automatic comment on behalf of dmitry@zend.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=8fc934b0a1781bc0685775f4c476c6704d796a76
Log: Fixed bug #71818 (Memory leak when array altered in destructor)
 [2016-10-17 10:11 UTC] bwoebi@php.net
-Status: Assigned +Status: Closed
 [2016-10-17 13:27 UTC] nikic@php.net
-Status: Closed +Status: Re-Opened
 [2016-10-17 13:27 UTC] nikic@php.net
Someone messed the repo again, reopening.
 [2017-10-24 05:20 UTC] kalle@php.net
-Status: Re-Opened +Status: Assigned
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Sun Nov 19 01:31:42 2017 UTC