snowrlily / pb4php

Automatically exported from code.google.com/p/pb4php
0 stars 0 forks source link

Memory leaks in PBMessage #3

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
The PBMessage class has memory leaks issues in PHP 5. The solution is to 
add a __destruct() method, and manually call __destruct() and unset() on 
every used object. This code has been proven no memory leaks by the use of 
memory_get_usage() function.

The right way of dealing with PBMessage object.
=====================================
$pb = new PB_MessageObjectExample()
$pb->ParseFromString('....');
   :   :   :
   :   :   :
$pb->__destruct();
unset($pb);
=====================================

* PBMessage
=====================================
abstract class PBMessage
{
    /**
     * Fix Memory Leaks with Objects in PHP 5
     * http://paul-m-jones.com/?p=262
     */
    public function __destruct()
    {
        if (isset($this->reader))
        {
            unset($this->reader);
        }
        if (isset($this->value))
        {
            unset($this->value);
        }
        // base128
        if (isset($this->base128))
        {
           unset($this->base128);
        }
        // fields
        if (isset($this->fields))
        {
            foreach ($this->fields as $name => $value)
            {
                unset($this->$name);
            }
            unset($this->fields);
        }
        // values
        if (isset($this->values))
        {
            foreach ($this->values as $name => $value)
            {
                if (is_array($value))
                {
                    foreach ($value as $name2 => $value2)
                    {
                        if (is_object($value2) AND method_exists
($value2, '__destruct'))
                        {
                            $value2->__destruct();
                        }
                        unset($value2);
                    }
                    unset($value->$name2);
                }
                else
                {
                    if (is_object($value) AND method_exists
($value, '__destruct'))
                    {
                        $value->__destruct();
                    }
                    unset($value);
                }
                unset($this->values->$name);
            }
            unset($this->values);
        }
    }
}
=====================================

Original issue reported on code.google.com by che...@gmail.com on 10 Mar 2009 at 6:10

GoogleCodeExporter commented 8 years ago
[24]

Original comment by kordu...@googlemail.com on 23 Mar 2009 at 7:12

GoogleCodeExporter commented 8 years ago
The problem with that is that __destruct can be called during object 
serialization as well, automatically. In that case, serialization is crashing.
If you want to use that method, change its name to non-magic name.

Original comment by liorbenkereth on 20 Jul 2010 at 4:25