Bug #79518 [NEW]: SimpleXML memory leak

From: Date: Fri, 24 Apr 2020 10:35:27 +0000
Subject: Bug #79518 [NEW]: SimpleXML memory leak
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-226757@lists.php.net to get a copy of this message
From:             ivo at beerntea dot com
Operating system: Linux
PHP version:      7.3.17
Package:          SimpleXML related
Bug Type:         Bug
Bug description:SimpleXML memory leak

Description:
------------
SimpleXML and DOMDocument (and possibly other libxml functions) do not
always free the allocated memory after all references to the XML/DOM
object have been released.

This especially is a problem in environments where the same process is
used to handle multiple requests, like the FPM interface, as memory
allocated by one script won't be released until the FPM process is
terminated. When handling large XML files this can easily push a server
out of memory.

In addition the XML DOM appeard to use significantly more memory than
the original XML string, and the memory used by the XML DOM is not
accounted for by PHP (see #63380), allowing to bypass the PHP memory
limit.

PHP version: 7.3.17-1+ubuntu18.04.1+deb.sury.org+1
Linux kernel 4.15.0-91-generic x86_64

Test script:
---------------
<?php
function mstat() {
  //Print reserved memory according to PHP and total mapped memory
according to OS (assumes 4k page size and Linux) 
  $statm = explode(' ', file_get_contents('/proc/self/statm'));
  printf("PHP memory usage=%u MB, process memory usage=%u MB\n",
memory_get_usage(TRUE) / 1024 / 1024, $statm[0] * 4096 / 1024 / 1024);
}

mstat();

$xml = '<doc>'.str_repeat('<node
attr="attr">test</node>',
1000000).'</doc>';
printf("Preparing big XML: %u MB.\n", strlen($xml) / 1024 / 1024);
mstat();

$flags = 0;
$flags |= LIBXML_COMPACT; //COMPACT flag reduces memory usage a little
bit, not much

echo "Parsing DOM document without storing reference...\n";
(new \DOMDocument())->loadXML($xml, $flags);
mstat();

echo "Parse XML DOM without storing reference...\n";
simplexml_load_string($xml, 'SimpleXMLElement', $flags);  
mstat();

echo "Parse XML DOM without storing reference...\n";
simplexml_load_string($xml, 'SimpleXMLElement', $flags);  
mstat();

echo "Parse XML DOM storing reference...\n";
$dom = simplexml_load_string($xml, 'SimpleXMLElement', $flags);  
mstat();

echo "Parse XML DOM overwriting reference...\n";
$dom = simplexml_load_string($xml, 'SimpleXMLElement', $flags);  
mstat();

echo "Unset XML string...\n";
$xml = NULL;
mstat();

echo "Unset DOM references...\n";
$dom = $dom2 = $dom3 = NULL;
mstat();

Expected result:
----------------
Indicated memory usage should return back to the initial value after a
reference to the XML/DOM object is cleared.

Actual result:
--------------
The memory used by the XML functions remains in use even when there are
no more references:

PHP memory usage=2 MB, process memory usage=391 MB
Preparing big XML: 27 MB.
PHP memory usage=29 MB, process memory usage=419 MB
Parsing DOM document without storing reference...
PHP memory usage=29 MB, process memory usage=892 MB


-- 
Edit bug report at https://bugs.php.net/bug.php?id=79518&edit=1
-- 
Fix committed:                    https://bugs.php.net/fix.php?id=79518&r=fixed
Fixed in release:                 https://bugs.php.net/fix.php?id=79518&r=alreadyfixed
Need backtrace:                   https://bugs.php.net/fix.php?id=79518&r=needtrace
Need Reproduce Script:            https://bugs.php.net/fix.php?id=79518&r=needscript
Try newer version:                https://bugs.php.net/fix.php?id=79518&r=oldversion
Not developer issue:              https://bugs.php.net/fix.php?id=79518&r=support
Expected behavior:                https://bugs.php.net/fix.php?id=79518&r=notwrong
Not enough info:                  https://bugs.php.net/fix.php?id=79518&r=notenoughinfo
Submitted twice:                  https://bugs.php.net/fix.php?id=79518&r=submittedtwice
register_globals:                 https://bugs.php.net/fix.php?id=79518&r=globals
PHP version support discontinued: https://bugs.php.net/fix.php?id=79518&r=phptooold
Daylight Savings:                 https://bugs.php.net/fix.php?id=79518&r=dst
IIS Stability:                    https://bugs.php.net/fix.php?id=79518&r=isapi
Install GNU Sed:                  https://bugs.php.net/fix.php?id=79518&r=gnused
Floating point limitations:       https://bugs.php.net/fix.php?id=79518&r=float
No Zend Extensions:               https://bugs.php.net/fix.php?id=79518&r=nozend
MySQL Configuration Error:        https://bugs.php.net/fix.php?id=79518&r=mysqlcfg


Thread (8 messages)

« previous php.bugs (#226757) next »