ZF-9504: Zend_XmlRpc_Generator: memory leak

Issue Type: Bug Created: 2010-03-22T04:06:47.000+0000 Last Updated: 2010-04-27T11:13:50.000+0000 Status: Resolved Fix version(s): - 1.10.4 (28/Apr/10)

Reporter: Sascha Wojewsky (wojewsky) Assignee: Matthew Weier O'Phinney (matthew) Tags: - Zend_XmlRpc_Server

Related issues: - ZF-8457

Attachments: - trace.xt.bz2


With Zend Framework 1.9.5 we've any problems with our xmlrpc-server. Now (with 1.10.2) we've got this error: PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 220715 bytes) in /usr/local/zend/share/ZendFramework/library/Zend/XmlRpc/Generator/GeneratorAbstract.php on line 127

I've tried both: - Zend_XmlRpc_Value::setGenerator(new Zend_XmlRpc_Generator_XmlWriter()); - Zend_XmlRpc_Value::setGenerator(new Zend_XmlRpc_Generator_DomDocument());

Best Regards Sascha Wojewsky


Posted by David Abdemoulaie (hobodave) on 2010-04-26T18:47:54.000+0000

I have been able to duplicate this memory leak as well, please view the attached xdebug trace. (45M, 1.2M compressed).

Things to note:

The return value from this xmlrpc call is an array in the following format:

<pre class="literal">
    'values' => array(
        0 => array(
            'id' => 1,
            'name' => 'Foobar',
            'group_id' => 7,
            'priority' => 0,
       // ...
       740 => array(/* ... */),
    'last_modified' => '2010-01-01 00:00:00',

The entire resultset is loaded into the PHP array format between lines 5577348 and 6837560. This increases script memory usage by 1.2M for a total of 6.6M.

Line 63810 Zend_XmlRpc_Response->__toString(), invoked marking beginning of copying the PHP array into the corresponding Zend_XmlRpc_Value object graph - current usage 6.5M

Line 86148 - Zend_XmlRpc_Value object graph construction completes - current usage 8.7M

Line 86245 - Zend_XmlRpc_Generator_GeneratorAbstract->__toString() invoked, leak begins - current usage 9072432 bytes

Now continue searching the document for invocations of Zend_XmlRpc_Generator_GeneratorAbstract->__toString():

Line 86283 - Usage: 9072744 (312 byte increase) Line 86321 - Usage: 9073144 (400 byte increase) Line 86349 - Usage: 9073612 (468 byte increase) ... Line 247124 - Usage: 726055636 Line 247162 - Usage: 726371428 (315792 byte increase) Line 247200 - Usage: 726687288 (315860 byte increase)

The memory usage continues to increase exponentially. You can view this easily by simply grepping for Zend_XmlRpc_Generator_GeneratorAbstract->stripDeclaration() and noting the increasing deltas in column 3. By the time the script crashes, each call to saveXml() is increasing the memory usage by over 300KB.

There is clearly something wrong here, though I haven't yet figured out yet.

The memory usage is increasing exponentially, but the rate of increase is linear. This leads me to believe it's a problem similar to:

<pre class="literal">

$o = new stdClass();
$o->str = 'abc';

$arr = array($o);
for ($i = 0; $i < 100; $i++) {
    $o = clone $o; 
    $o->str .= 'abc';
    $arr[] = $o; 

Posted by David Abdemoulaie (hobodave) on 2010-04-27T10:09:20.000+0000

I have confirmed my suspicions from the example above. Each Zend_XmlRpc_Value node has an $_xml property. During the _generateXml() methods the Generator is reused, thus a full copy of the DOM as xml is saved at each node.


First Node

<pre class="highlight">
<?xml version="1.0"?>

Second Node

<pre class="highlight">
<?xml version="1.0"?>
updatesid1nameRelocate / Remove

Third Node

<pre class="highlight">
<?xml version="1.0"?>
updatesid1nameRelocate / Removedescription

Posted by Matthew Weier O'Phinney (matthew) on 2010-04-27T11:13:48.000+0000

Patch created by hobodave, and applied by matthew in trunk and 1.10 release branch; saw improvements of 1GB memory usage -> 8.8MB after patch, and > 300% decrease in time needed to execute.

Will release with 1.10.4.

Have you found an issue?

See the Overview section for more details.


© 2006-2016 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.