Bug #65743 [Opn->Csd]: Memory leak with opCache, XML and continue
| From: | nikic@php.net | Date: | Fri, 19 Dec 2014 20:59:07 +0000 |
| Subject: | Bug #65743 [Opn->Csd]: Memory leak with opCache, XML and continue | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-189137@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=65743&edit=1
ID: 65743
Updated by: nikic@php.net
Reported by: thomas dot koenig at web-eci dot com
Summary: Memory leak with opCache, XML and continue
-Status: Open
+Status: Closed
Type: Bug
Package: opcache
Operating System: Debian Wheezy x64
PHP Version: 5.4.20
-Assigned To:
+Assigned To: nikic
Block user comment: N
Private report: N
New Comment:
Fixed, see also https://bugs.php.net/bug.php?id=67111.
Previous Comments:
------------------------------------------------------------------------
[2014-12-18 08:05:17] david dot guyot at web-eci dot com
I am the sysadmin of Thomas Koenig, the bug reporter. Regarding the StackOverflow topic, I can
confirm that, on our system, Opcache is active with full optimization, ie. 0xFFFFâ¦
------------------------------------------------------------------------
[2014-12-18 02:04:28] thilo at eightysoft dot de
Some other information on this bug can be found here: https://stackoverflow.com/questions/23231675/php-5-5-memory-leak-when-using-continue-2-inside-two-foreach-loops
------------------------------------------------------------------------
[2014-12-17 11:08:33] php dot net at kingsquare dot nl
Just confirmed that this is still a real issue (tested with this exact same script on 5.6.3 /
opdache 7.0.4-dev)
A work around for this issue that works is by having a label present and using 'goto' to
mitigate the foreach. Something seems to be off with 'continue X' (where X is a level)
------------------------------------------------------------------------
[2013-09-23 15:18:13] thomas dot koenig at web-eci dot com
Description:
------------
Hello, everybody.
I noticed a problem while parsing XML with interlocked foreach loops : if I
write 'continue 2' to continue the upper loop, this will consume virtual memory
far faster than with a single 'continue' or 'break'.
In my exemple, I parse a small basic XML; when I use 'continue 2', I see that as
much as 8MB are used for this tiny loop. (See actual result)
On the other hand, only around 256kB are used if I replace this 'continue 2'
with 'break 2' (See expected result).
As you can see, this 'continue 2' leads the script to retain much more memory
than needed, and that this virtual memory is retained even if the loops
allocating this memory are finished. Furthermore, we used the 'continue 2'
version on a server when parsing a 37MB XML file, and this leaded the script to
fail because the OS prevented it to claim more than 2GB of virtual memory; as
you can see, this isn't only a theoritical issue.
Awaiting a bugfix,
Regards.
Test script:
---------------
function testOpCache(){
$tab1 = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
$tab2 = array('a', 'b', 'c', 'd', 'e',
'f', 'g', 'h', 'i', 'j');
$tab3 = array(1 => 'a', 2 => 'b', 3 => 'c', 4 =>
'd', 5 => 'e', 6 => 'f', 7 => 'g', 8 =>
'h', 9 => 'i', 10 => 'j');
$xml = "
<level1>
<level2>info1</level2>
<level2>info2</level2>
<level2>info3</level2>
<level2>info4</level2>
<level2>info5</level2>
<level2>
<level3>subinfo1</level3>
<level3>subinfo2</level3>
<level3>subinfo3</level3>
<level3>subinfo4</level3>
<level3>
<level4>subsubinfo1</level4>
<level4>subsubinfo2</level4>
<level4>subsubinfo3</level4>
<level4>subsubinfo4</level4>
</level3>
<level3>
<level4>subsubinfo1</level4>
<level4>subsubinfo2</level4>
<level4>subsubinfo3</level4>
<level4>subsubinfo4</level4>
</level3>
<level3>
<level4>
<level5>aaa</level5>
<level5>aaa</level5>
<level5>aaa</level5>
<level5>aaa</level5>
<level5>aaa</level5>
</level4>
<level4>subsubinfo2</level4>
<level4>
<level5>aaa</level5>
<level5>aaa</level5>
<level5>aaa</level5>
<level5>aaa</level5>
<level5>aaa</level5>
</level4>
<level4>subsubinfo4</level4>
</level3>
</level2>
<level2>
<level3>subinfo1</level3>
<level3>subinfo2</level3>
<level3>subinfo3</level3>
<level3>subinfo4</level3>
<level3>
<level4>subsubinfo1</level4>
<level4>subsubinfo2</level4>
<level4>subsubinfo3</level4>
<level4>subsubinfo4</level4>
</level3>
<level3>
<level4>subsubinfo1</level4>
<level4>subsubinfo2</level4>
<level4>subsubinfo3</level4>
<level4>subsubinfo4</level4>
</level3>
<level3>
<level4>
<level5>aaa</level5>
<level5>aaa</level5>
<level5>aaa</level5>
<level5>aaa</level5>
<level5>aaa</level5>
</level4>
<level4>subsubinfo2</level4>
<level4>subsubinfo3</level4>
<level4>
<level5>aaa</level5>
<level5>aaa</level5>
<level5>aaa</level5>
<level5>aaa</level5>
<level5>aaa</level5>
</level4>
</level3>
</level2>
</level1>
";
$dom = simplexml_load_string($xml);
$tab4 = array();
sm();
foreach($tab1 as $t1){
foreach($tab2 as $t2){
foreach($tab3 as $t3){
foreach($dom->xpath('/level1/level2') as $level2){
foreach($level2->xpath('level3') as $level3){
foreach($level3->xpath('level4') as $level4){
foreach($level4->xpath('level5') as $level5){
continue 2;
//break 2;
}
}
}
}
}
}
}
sm();
}
function sm(){
echo memory_get_usage()."\n";
}
testOpCache();
Expected result:
----------------
thomas@Koenig:~$ php /home/thomas/Desktop/tests/opcache-1.php
239224
240120
thomas@Koenig:~$
Actual result:
--------------
thomas@Koenig:~$ php /home/thomas/Desktop/tests/opcache-1.php
239200
8416616
thomas@Koenig:~$
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=65743&edit=1