php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #38604 Memory leak in SimpleXML ?
Submitted: 2006-08-26 06:51 UTC Modified: 2007-01-10 16:12 UTC
Votes:11
Avg. Score:5.0 ± 0.0
Reproduced:11 of 11 (100.0%)
Same Version:6 (54.5%)
Same OS:4 (36.4%)
From: apachephp at gmail dot com Assigned:
Status: Closed Package: SimpleXML related
PHP Version: 5.1.5 OS: Linux
Private report: No CVE-ID: None
 [2006-08-26 06:51 UTC] apachephp at gmail dot com
Description:
------------
I'm processing big XML file (1-10MB each) in loop.
Very soon free memory is near to zero and system starts swapping.

Reproduce code:
---------------
<?
function ProcessFile($filename)
{
        if (file_exists($filename)) {
                $xml = simplexml_load_string(file_get_contents($filename));
                foreach ($xml->report as $reports)
                {
                        //echo $reports->forumid."\n";
                }
                //   var_dump($xml);
                unset($xml);
        } else {
                exit('Failed to open test.xml.');
        }

}


$files=file('files.txt');

foreach ($files as $file)
{
        $file=chop($file);

        echo "Processing $file\n";
        ProcessFile($file);
}

?>


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-08-28 06:16 UTC] tony2001@php.net
Please try using this CVS snapshot:

  http://snaps.php.net/php5.2-latest.tar.gz
 
For Windows:
 
  http://snaps.php.net/win32/php5.2-win32-latest.zip


 [2006-08-28 07:30 UTC] apachephp at gmail dot com
the same problem with php5.2-200608280630
 [2006-08-28 07:56 UTC] tony2001@php.net
Cannot reproduce.
 [2006-08-28 07:58 UTC] apachephp at gmail dot com
is it OK if I upload my XML files somewhere ?
 [2006-08-28 08:09 UTC] tony2001@php.net
I don't think you really need 10Mb file to reproduce it.
If it really leaks, then it should do it even with 10 bytes XML file.
 [2006-08-28 08:46 UTC] apachephp at gmail dot com
Well, I don't have XML files with 10 bytes,
and with 10Mb files my memory is exhausted after processing 20 files.
Memory is OK if I am processing files one per run.
 [2006-08-28 08:49 UTC] tony2001@php.net
Thank you for this bug report. To properly diagnose the problem, we
need a short but complete example script to be able to reproduce
this bug ourselves. 

A proper reproducing script starts with <?php and ends with ?>,
is max. 10-20 lines long and does not require any external 
resources such as databases, etc. If the script requires a 
database to demonstrate the issue, please make sure it creates 
all necessary tables, stored procedures etc.

Please avoid embedding huge scripts into the report.


 [2006-08-28 09:48 UTC] apachephp at gmail dot com
script:

<?php

$XML='<TAG1>
<TAG2>
<TAG3>6809586b1c38100f</TAG3>
<TAG4>4323ac020</TAG4>
<TAG5>NULL</TAG5>
<TAG6>4323ac04e</TAG6>
<TAG7>ihttp://www.mysqlperformanceblog.com/</TAG7>
<TAG8>Who AM I</TAG8>
<TAG9>00000232343d3062</TAG9>
<TAG10>204923</TAG10>
<TAG11>http://www.mysqlperformanceblog.com/</TAG11>
<TAG12>http://www.mysqlperformanceblog.com/</TAG12>
<TAG13 date="2006-08-22 11:44:00">
<TAG14></TAG14>
<TAG15>Apachephp
</TAG15>
<TAG16>
Thank you for this bug report. To properly diagnose the problem, we

need a short but complete example script to be able to reproduce

this bug ourselves.

</TAG16>
<TAG17></TAG17>
<TAG18></TAG18>
<TAG19>0</TAG19>
<TAG20></TAG20>
</TAG13>
<TAG21></TAG21>
<TAG22></TAG22>
<TAG23>2006-08-22 23:19:43</TAG23>
<TAG24>Qwerrt</TAG24>
<TAG25>1</TAG25>
<TAG26>http://www.mysqlperformanceblog.com/</TAG26>
<TAG27>http://www.mysqlperformanceblog.com/</TAG27>
<TAG28>1</TAG28>
<TAG29>918180</TAG29>
<TAG30> MySQL Performance tuning optimization consulting</TAG30>
<TAG31></TAG31>
<TAG32>Simple XML </TAG32>
<TAG33>0</TAG33>
<TAG34>0</TAG34>
<TAG35>1</TAG35>
<TAG35></TAG35>
<TAG36></TAG36>
</TAG2>
</TAG1>';

function ProcessFile($filename)
{
        global $XML;
                $xml = simplexml_load_string($XML);
                echo "Memory: ".memory_get_usage() . "\n";
                foreach ($xml->report as $reports)
                {
                        //echo $reports->forumid."\n";
                }
                //   var_dump($xml);
                unset($xml);

}


while(true)
{

        ProcessFile($file);
        echo "Loop ".($i++).", memory used: ".memory_get_usage() . "\n";
}


?>


output:
Loop 1, memory used: 57844
...

Loop 1000, memory used: 269632
..
Loop 5000, memory used: 1461740
..
Loop 10000, memory used: 2914996

Loop 65531, memory used: 17047104
Memory: 17047104

Fatal error: Allowed memory size of 16777216 bytes exhausted (tried to allocate 3145728 bytes) in /mnt/data/home/vadim/testfeed/testxml2.php on line 57
 [2006-09-19 09:26 UTC] rolfdw at gmail dot com
I dont know if this will help anyone but I found that it is the foreach that actually causes the memory leak. If you replace the FOREACH with a FOR loop it seems to be stable.
 [2006-09-21 16:05 UTC] scope at planetavent dot de
Hi!

A shorter version that quickly eats up all the memory:

<?php
  $xml = '<root><node></node></root>';
  
  $xmldata = simplexml_load_string( $xml );
  
  while( true )
  {
    foreach ( $xmldata->node as $node )
    {
    }
  }  
?>

(php5.1.5, WinXP, Shell)

Also tried the latest snapshot, same effect.
 [2006-10-15 00:33 UTC] no_spam_please at obmud dot com
Hi folks:

Bug report # 34112, which apparently addresses the same 
issue, ends with a note from a PHP developer that this is 
not a "bug."

Bug or not, this is a problem and -- in my opinion -- should 
be resolved if object-oriented PHP is intended to be used, 
among other things, a CLI language.

As one of the commenters points out, the memory depletion 
appears to stem from using an object inside a foreach.

By the way, the following hack fixes the above code, which 
otherwise exhausts the allowed memory size in a split 
second.

Yours truly,
Hakan

<?php
  $xml = '<root><node></node></root>';
  $xmldata = simplexml_load_string($xml);
  while (true) {
    $foo = $xmldata->node;
    foreach ($foo as $node)
    {
    }
  }
?>
 [2007-01-10 16:12 UTC] iliaa@php.net
This bug has been fixed in CVS.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Mar 19 11:01:28 2024 UTC