ID: 48643
Comment by: robin_fernandes at uk dot ibm dot com
Reported By: [email protected]
Status: Open
Bug Type: SPL related
Operating System: Linux (Ubuntu)
PHP Version: 5.2CVS-2009-06-22 (CVS)
New Comment:
Testcase below shows that the issue relates to an implicit cast to
string on an SplFileInfo object when retrieved from a
RecursiveDirectoryIterator during iteration.
<?php
$rdi = new RecursiveDirectoryIterator('/manyFiles');
echo "SplFileInfo explicit cast to string: ";
foreach ($rdi as $v) { strlen((string)$v); } //OK
echo memory_get_usage(true) . PHP_EOL;
echo "SplFileInfo implicit cast to string: ";
foreach ($rdi as $v) { strlen($v); } //Leaky
echo memory_get_usage(true) . PHP_EOL;
?>
php52:
SplFileInfo explicit cast to string: 262144
SplFileInfo implicit cast to string: 262144
php53:
SplFileInfo explicit cast to string: 524288
SplFileInfo implicit cast to string: 6291456
Previous Comments:
------------------------------------------------------------------------
[2009-06-23 13:02:34] [email protected]
Looking backwards through PHP builds I have currently narrowed this
down to a change that went in to PHP 5.3 somewhere between the 12th June
2008 and the 1st July 2008.
------------------------------------------------------------------------
[2009-06-23 12:13:49] robin_fernandes at uk dot ibm dot com
Below is a simplified testcase which I think exposes the same leak.
'/manyFiles' is a directory containing 10000 files.
<?php
$rii = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator('/manyFiles')
);
function noop() {}
echo "noop call in loop (no leak) : ";
foreach ($rii as $v) { noop($v); }
echo memory_get_usage() . PHP_EOL;
echo "strlen call in loop (leak on 53) : ";
foreach ($rii as $v) { strlen($v); }
echo memory_get_usage() . PHP_EOL;
?>
Output on php52:
noop call in loop (no leak) : 66176
strlen call in loop (leak on 53) : 66176
Output on php53:
noop call in loop (no leak) : 337448
strlen call in loop (leak on 53) : 6028496
------------------------------------------------------------------------
[2009-06-22 14:33:05] [email protected]
I tested with PHP 5.2 but do not see the same issue. I believe this is
specific to PHP 5.3.
------------------------------------------------------------------------
[2009-06-22 12:32:02] [email protected]
By the way, I traced the memory consumption using xdebug:
xdebug.auto_trace = on;
xdebug.show_mem_delta = on;
The first few lines are here http://pastebin.ca/1469804
This makes it look more like a bug with the way the accept() method is
invoked inside PhptFilterIterator.
------------------------------------------------------------------------
[2009-06-22 11:41:59] [email protected]
Description:
------------
An excessive about of memory is used when a class which extends
FilterIterator is used to filter for certain file types when scanning a
source tree.
Reproduce code:
---------------
A small benchmark is provided in the tar file
here:http://filebin.ca/okgvtt/memcheck.tar
The file contains three tests which all use code in Util.php.
To run the tests edit the shell script memcheck to add the top level
directory of a PHP source tree as input to each test. Then just execute
the shell script.
The benchmarks produce a list of directories which contain .phpt files,
the memory usage when the class PhptFilterIterator is used is 20 times
higher than the other two methods.
Expected result:
----------------
Would expect the memory usage to be similar.
Actual result:
--------------
Memory usage is 20 times higher.
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=48643&edit=1