在两个foreach循环中使用“continue 2”时,php 5.5内存泄漏?

I just came across a strange memory leak issue. I managed to track the problem down to the following code:

<?php
$data=array();
for($c=0; $c<32768; $c++)
    $data[$c]=array(1, 2, 3);
$filter=array(1, 2, 3);

for($kc=0; $kc<25600; $kc++)
{
    $cm=memory_get_usage(true);
    $pm=memory_get_peak_usage(true);
    echo "<b>loop $kc: current_memory: $cm, peak_memory: $pm...</b><br>";
    flush();

    foreach($data as $entry)
        foreach($filter as $pattern)
            continue 2;
}
?>

Output:

loop 0: current_memory: 12582912, peak_memory: 12582912...
loop 1: current_memory: 20709376, peak_memory: 20709376...
loop 2: current_memory: 28835840, peak_memory: 28835840...
loop 3: current_memory: 36962304, peak_memory: 36962304...
loop 4: current_memory: 45088768, peak_memory: 45088768...
loop 5: current_memory: 53215232, peak_memory: 53215232...
loop 6: current_memory: 61341696, peak_memory: 61341696...
loop 7: current_memory: 69468160, peak_memory: 69468160...
loop 8: current_memory: 77594624, peak_memory: 77594624...
loop 9: current_memory: 85721088, peak_memory: 85721088...
loop 10: current_memory: 93847552, peak_memory: 93847552...
loop 11: current_memory: 101974016, peak_memory: 101974016...
loop 12: current_memory: 110100480, peak_memory: 110100480...
loop 13: current_memory: 118226944, peak_memory: 118226944...
loop 14: current_memory: 126353408, peak_memory: 126353408...
loop 15: current_memory: 134479872, peak_memory: 134479872...
loop 16: current_memory: 142606336, peak_memory: 142606336...
loop 17: current_memory: 151257088, peak_memory: 151257088...
loop 18: current_memory: 159383552, peak_memory: 159383552...
loop 19: current_memory: 167510016, peak_memory: 167510016...
loop 20: current_memory: 175636480, peak_memory: 175636480...
loop 21: current_memory: 183762944, peak_memory: 183762944...
loop 22: current_memory: 191889408, peak_memory: 191889408...
loop 23: current_memory: 200015872, peak_memory: 200015872...
loop 24: current_memory: 208142336, peak_memory: 208142336...
loop 25: current_memory: 216268800, peak_memory: 216268800...
loop 26: current_memory: 224395264, peak_memory: 224395264...
loop 27: current_memory: 232521728, peak_memory: 232521728...
loop 28: current_memory: 240648192, peak_memory: 240648192...
loop 29: current_memory: 248774656, peak_memory: 248774656...
loop 30: current_memory: 256901120, peak_memory: 256901120...
loop 31: current_memory: 265027584, peak_memory: 265027584...
Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 40 bytes) in xxx

When I remove the "continue 2" statement and use a simple "break" or "continue", the memory usage stays constant. Can anyone confirm this strange behavior? Did I find a memory leak bug in php 5.5? Using php-cli doesn't show this strange behavior. Only using php as mod_php inside apache shows this behavior.

My System:

$ php --version
PHP 5.5.11-2 (cli) (built: Apr  8 2014 11:42:22) 
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies
    with Zend OPcache v7.0.4-dev, Copyright (c) 1999-2014, by Zend Technologies

$ apache2ctl status
Apache Server Status for localhost (via ::1)

   Server Version: Apache/2.4.9 (Debian)
          mod_fastcgi/mod_fastcgi-SNAP-0910052141 PHP/5.5.11-2
          mod_perl/2.0.8 Perl/v5.18.2

   Server MPM: prefork
   Server Built: Mar 29 2014 21:52:01

I'm on current Debian testing (Jessie).

Thanks for your help!

donpb2823
donpb2823 我在1周内敲打我的脑袋,以便在我的应用程序中找到内存泄漏的根本原因,我已经检查了每行数百次,但没有发现任何可疑的东西,然后我想到了“继续2”行并且搜索引导我到这个页面......嗯..那个f**王虫在整个星期都破坏了。看起来我并不孤单。
4 年多之前 回复
dongtun1683
dongtun1683 cron-expressionlib/project似乎有同样的问题github.com/mtdowling/cron-expression/issues/50
6 年多之前 回复
dongmo8943
dongmo8943 是!而已!我禁用了opcache,一切都按预期运行。从PHP5.4到5.5的更新覆盖了我的php.ini,这似乎启用了opcache。谢谢你的提示!你想写一个答案,以便我接受吗?:)
6 年多之前 回复
duanbi3786
duanbi3786 你能禁用ZendOPcache吗?我以前遇到过麻烦(没注意到一些用过的文件有变化)。
6 年多之前 回复
doudoulb1234
doudoulb1234 嗯,这很奇怪。我不知道我的php版本有什么特别之处。好的,我刚刚在php-cli中测试了我的代码->没有内存泄漏。我正在使用apache2.4.9。(更新了我的问题并包含了我的apache版本信息)。
6 年多之前 回复
dqyanc7264
dqyanc7264 虽然他们认为滥用他们的资源但没有在3v4l.org上看到任何版本的证据...对不起3v4l人
6 年多之前 回复
dppn67180
dppn67180 在本地和viper7上测试你的代码,没有泄漏。
6 年多之前 回复

2个回答



WAIT !! </ h2>

您不应该禁用opcache:以及缓存,opcache执行优化 。</ p>

优化意味着opcache 更改已编译的操作码</ em>。</ p>

我确信调优优化就是这种情况 将告诉你bug的引入位置,这意味着你可以在bugs.php.net上创建一个bug报告,我们有机会为每个人解决问题。</ p>

请带上 是时候了。</ p>

调优优化</ h2>

Opcache有几个优化传递, https://gist.github.com/krakjoe/962e54c38b155f896b00 </ p>

配置运行的通行证是一个改变的问题< 您的配置中的代码> opcache.optimization_level </ code>,这是一个位掩码,默认为 0xffffffff </ code>。</ p>

如果您需要帮助调试,请访问#php.pecl 在EFnet上。</ p>

注意:要有操作 在php-cli中启用缓存,将 opcache.enable_cli </ code>更改为 1 </ code>,这将允许您在控制台中进行测试,同样的行为应该自行显示</ em> </ p >
</ div>

展开原文

原文

WAIT !!

You should not disable opcache: as well as caching, opcache performs optimization.

Optimization means that opcache changes the compiled opcodes.

I am certain that it is the case that tuning optimization will show you where the bug is introduced, this will mean you can create a bug report at bugs.php.net and we have a chance of fixing the problem for everyone.

Please take the time to do this, please.

Tuning Optimization

Opcache has several optimization passes, https://gist.github.com/krakjoe/962e54c38b155f896b00

Configuring which passes run is a matter of changing opcache.optimization_level in your configuration, this is a bitmask, by default 0xffffffff.

If you need help debugging visit #php.pecl on EFnet.

Note: to have opcache enabled in php-cli, change opcache.enable_cli to 1, this will allow you to test in console, the same behaviour should display itself

dongmei8760
dongmei8760 0xF0000000传递1,0xFF000000传递2,依此类推......
6 年多之前 回复
dsen53898
dsen53898 好,我会试试。 位掩码中的哪个条目对应于什么优化传递? 通过1有0x00000001,通过2 0x00000002,依此类推?
6 年多之前 回复



仅为记录,“继续2”错误仍在5.5和5.6.3下验证( https://bugs.php.net/bug.php?id=65743 )。 一个解决方法是使用'goto-hack'而不是继续但是在第一个foreach中'返回'到一个定义的标签...我知道,f * gly但是有效(与</ em> opcache) </ p>
</ div>

展开原文

原文

Just for the record the "continue 2" bug is verified still under 5.5 and 5.6.3 (https://bugs.php.net/bug.php?id=65743). One work around is to utilize the 'goto-hack' and not continue but go 'back' to a defined label in the first foreach... i know, f*gly but works (with opcache)

duaijiao0648
duaijiao0648 是的,修复了那些版本,如更改日志中所示:php.net/ChangeLog-5.php#5.5.21
接近 5 年之前 回复
dongyi1159
dongyi1159 现在修复了这个bug,看到这个提交:git.php.net / ...有希望包含在即将发布的版本5.5.21和5.6.5中
5 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐