php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #79392 get_object_vars() memory leak
Submitted: 2020-03-18 12:01 UTC Modified: 2020-07-07 11:09 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: tomas914 at gmail dot com Assigned:
Status: Re-Opened Package: Performance problem
PHP Version: Irrelevant OS: Windows 10
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: tomas914 at gmail dot com
New email:
PHP Version: OS:

 

 [2020-03-18 12:01 UTC] tomas914 at gmail dot com
Description:
------------
I'm developing an app which uses storage with fairly large amount of objects that are created from unserialized cached data.

Objects properties are set by iterating through get_object_vars() which causes extremely high memory usage.

Provided is reduced test case for reproducing this issue. The difference between two create functions is only the amount of get_object_vars() calls which leads me to conclusion it's a memory leak.

Results are:
Create(): Memory usage: 28.72MB
CreateWithLeak(): Memory usage: 95.1MB

Test script:
---------------
abstract class ObjectVarsCache
{
    public static $vars = array();
}

class Test
{
    public $a;
    public $b;
    public $c;
    public $d;
    public $e;
    public $f;
    public $g;
    public $h;
    public $i;
    public $j;

    public function CreateWithLeak()
    {
        $vars = get_object_vars($this);
    }

    public function Create()
    {
        $vars = &ObjectVarsCache::$vars;
        if (!$vars)
            $vars = get_object_vars($this);
    }
}

$objects = array();

for ($i = 0; $i < 100000; ++$i)
{
    $object = new Test;
    //$object->Create(); // uncomment to compare
    $object->CreateWithLeak();

    $objects []= $object;
}

echo "Memory usage: ".round(memory_get_usage() / 1024 / 1024, 2)."MB, Peak memory usage: ".round(memory_get_peak_usage() / 1024 / 1024, 2)."MB";


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-03-18 12:05 UTC] tomas914 at gmail dot com
Issue is present in all PHP versions since at least 7.0, didn't test earlier ones.
 [2020-03-18 14:14 UTC] cmb@php.net
-Status: Open +Status: Not a bug -Assigned To: +Assigned To: cmb
 [2020-03-18 14:14 UTC] cmb@php.net
The supposed "leak" is the properties table of the objects, which
is built lazily, because it is often not needed.  However,
get_object_vars() requires the table to be built, and it is only
freed when the object is destroyed.
 [2020-07-07 10:31 UTC] robert at korulczyk dot pl
This really should be documented at https://www.php.net/manual/en/function.get-object-vars.php, since this is very surprising behavior. I have very similar use case where `get_object_vars($this)` was used in `toArray()` method. Finding source of memory usage increase took me 2-3 hours, because `get_object_vars()` was the last thing I suspected to leak. Especially that manually building this array does not affect memory usage.

No leak:

```
	public function toArray(): array {
		return [
			'a' => $this->a,
			'b' => $this->b,
			'c' => $this->c,
			'd' => $this->d,
			'e' => $this->e,
			'f' => $this->f,
			'g' => $this->g,
			'h' => $this->h,
			'i' => $this->i,
			'j' => $this->j,
		];
	}
```

Leak:

```
	public function toArray(): array {
		return get_object_vars($this);
	}
```
 [2020-07-07 11:09 UTC] cmb@php.net
-Status: Not a bug +Status: Re-Opened -Type: Bug +Type: Documentation Problem -Assigned To: cmb +Assigned To:
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Thu Jan 02 11:01:29 2025 UTC