突然之间,我的应用程序出现了问题,这是我以前从未遇到的问题。我决定检查Apache的错误日志,我发现一条错误消息“zend_mm_heap corrupted”。这是什么意思。
操作系统:Fedora Core 8 Apache:2.2.9 PHP:5.2.6答案 0 :(得分:51)
经过多次试验和错误,我发现如果我增加php.ini文件中的output_buffering
值,则此错误消失
答案 1 :(得分:45)
我在PHP 5.5下遇到同样的错误,并且增加输出缓冲没有帮助。我没有运行APC,所以这不是问题。我终于将它追溯到 opcache ,我只需要从cli中禁用它。有一个特定的设置:
opcache.enable_cli=0
切换后,zend_mm_heap损坏的错误就消失了。
答案 2 :(得分:42)
如果你在Linux机器上,请在命令行上试试
export USE_ZEND_ALLOC=0
答案 3 :(得分:38)
这不是通过更改配置选项必须解决的问题。
更改配置选项有时会产生积极影响,但它可以轻易地使事情变得更糟,或者根本不做任何事情。
错误的本质是:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void) {
void **mem = malloc(sizeof(char)*3);
void *ptr;
/* read past end */
ptr = (char*) mem[5];
/* write past end */
memcpy(mem[5], "whatever", sizeof("whatever"));
/* free invalid pointer */
free((void*) mem[3]);
return 0;
}
上面的代码可以编译为:
gcc -g -o corrupt corrupt.c
使用valgrind执行代码,您可以看到许多内存错误,最终导致分段错误:
krakjoe@fiji:/usr/src/php-src$ valgrind ./corrupt
==9749== Memcheck, a memory error detector
==9749== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==9749== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==9749== Command: ./corrupt
==9749==
==9749== Invalid read of size 8
==9749== at 0x4005F7: main (an.c:10)
==9749== Address 0x51fc068 is 24 bytes after a block of size 16 in arena "client"
==9749==
==9749== Invalid read of size 8
==9749== at 0x400607: main (an.c:13)
==9749== Address 0x51fc068 is 24 bytes after a block of size 16 in arena "client"
==9749==
==9749== Invalid write of size 2
==9749== at 0x4C2F7E3: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9749== by 0x40061B: main (an.c:13)
==9749== Address 0x50 is not stack'd, malloc'd or (recently) free'd
==9749==
==9749==
==9749== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==9749== Access not within mapped region at address 0x50
==9749== at 0x4C2F7E3: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9749== by 0x40061B: main (an.c:13)
==9749== If you believe this happened as a result of a stack
==9749== overflow in your program's main thread (unlikely but
==9749== possible), you can try to increase the size of the
==9749== main thread stack using the --main-stacksize= flag.
==9749== The main thread stack size used in this run was 8388608.
==9749==
==9749== HEAP SUMMARY:
==9749== in use at exit: 3 bytes in 1 blocks
==9749== total heap usage: 1 allocs, 0 frees, 3 bytes allocated
==9749==
==9749== LEAK SUMMARY:
==9749== definitely lost: 0 bytes in 0 blocks
==9749== indirectly lost: 0 bytes in 0 blocks
==9749== possibly lost: 0 bytes in 0 blocks
==9749== still reachable: 3 bytes in 1 blocks
==9749== suppressed: 0 bytes in 0 blocks
==9749== Rerun with --leak-check=full to see details of leaked memory
==9749==
==9749== For counts of detected and suppressed errors, rerun with: -v
==9749== ERROR SUMMARY: 4 errors from 3 contexts (suppressed: 0 from 0)
Segmentation fault
如果你不知道,你已经发现mem
是堆分配的内存;堆指的是程序在运行时可用的内存区域,因为程序显式请求它(在我们的例子中使用malloc)。
如果您使用可怕的代码,您会发现并非所有明显不正确的语句都会导致分段错误(致命的终止错误)。
我在示例代码中明确地提出了这些错误,但是在内存管理环境中很容易发生同样的错误:如果某些代码没有维护变量(或其他符号)的引用计数正确的方法,例如,如果它过早自由,另一段代码可能从已经自由的内存中读取,如果它以某种方式存储地址错误,另一段代码可能写入无效内存,它可能是免费的两次......
这些不是可以在PHP中调试的问题,它们绝对需要内部开发人员的注意。
行动方针应该是:
可能没有任何利润......我在开始时说过,你可能会找到一种通过搞乱配置来改变你的症状的方法,但这是非常受欢迎和错过,并没有帮助下次有相同的zend_mm_heap corrupted
消息时,只有很多配置选项。
当我们发现错误时,我们创建错误报告非常重要,我们不能假设下一个遇到错误的人会去做...更可能的是,实际的解决方案是否定的如果你让合适的人知道这个问题,那就太神秘了。
如果在环境中设置USE_ZEND_ALLOC=0
,则会禁用Zend自己的内存管理器; Zend的内存管理器确保每个请求都拥有它自己的堆,所有内存在请求结束时都是空闲的,并且针对大小合适的内存块进行了优化对于PHP。
禁用它将禁用这些优化,更重要的是它可能会造成内存泄漏,因为有很多扩展代码依赖于Zend MM在请求结束时为它们释放内存(tut,tut)。
它也可能隐藏症状,但系统堆可能会以与Zend堆完全相同的方式被破坏。
它似乎更宽容或更不宽容,但修复问题的根本原因,它不能。
完全禁用它的能力是为了内部开发人员的利益;您应该从不部署PHP并禁用Zend MM。
答案 4 :(得分:22)
检查unset()
s。确保在析构函数中没有unset()
对$this
(或等价物)的引用,并且析构函数中的unset()
不会导致对同一对象的引用计数降至0我做了一些研究,发现通常会导致堆损坏。
发生PHP bug report about the zend_mm_heap corrupted错误。有关如何重现它的示例,请参阅注释[2011-08-31 07:49 UTC] f dot ardelian at gmail dot com
。
我感觉所有其他“解决方案”(更改php.ini
,使用更少的模块从源代码编译PHP等等)只是隐藏问题。
答案 5 :(得分:6)
对我来说,以前的答案都没有用,直到我尝试过:
opcache.fast_shutdown=0
到目前为止似乎有效。
我使用PHP 5.6与PHP-FPM和Apache proxy_fcgi,如果这很重要......
答案 6 :(得分:6)
在我的情况下,导致此错误的原因之一是阵列变得非常大。我已经设置了我的脚本以在每次迭代时重置数组并对问题进行排序。
答案 7 :(得分:5)
根据错误跟踪器,设置opcache.fast_shutdown=0
。快速关闭使用Zend内存管理器来清理它的混乱,这会禁用它。
答案 8 :(得分:3)
我和这个问题搏斗了一个星期,这对我有用,或至少看起来好像
在php.ini
进行这些更改
report_memleaks = Off
report_zend_debug = 0
我的设置是
Linux ubuntu 2.6.32-30-generic-pae #59-Ubuntu SMP
with PHP Version 5.3.2-1ubuntu4.7
这不起作用。
所以我尝试使用基准测试脚本,并尝试记录脚本挂起的位置。 我发现在错误发生之前,一个php对象被实例化,并且完成对象应该做的事情需要3秒多的时间,而在之前的循环中它需要最多0.4秒。我跑了几次这个测试,每次都一样。我想的不是每次都创建一个新对象(这里有一个很长的循环),我应该重用该对象。到目前为止,我已经对脚本进行了十几次测试,内存错误已经消失了!
答案 9 :(得分:3)
我认为这里没有一个答案,所以我会添加我的经验。我看到了同样的错误以及随机的httpd段错误。这是一个cPanel服务器。有问题的症状是apache会随机重置连接(没有在chrome中收到数据,或者在firefox中重置了连接)。这些似乎是随机的 - 大部分时间都是有效的,有时却没有。
当我到达现场时,输出缓冲为OFF。通过阅读这个暗示输出缓冲的线程,我打开它(= 4096)看看会发生什么。此时,他们所有开始显示错误。这很好,因为错误现在是可重复的。
我经历了并开始禁用扩展程序。其中,eaccellerator,pdo,ioncube loader以及其他很多人怀疑,但都没有帮助。
我终于找到了淘气的PHP扩展名为“homeloader.so”,它似乎是某种cPanel-easy-installer模块。删除后,我没有遇到任何其他问题。
在该注释中,看起来这是一个通用的错误消息,因此您的milage将随所有这些答案而变化,您可以采取最佳行动:
如果没有完成上述所有操作,您还可以尝试以下方式:
答案 10 :(得分:2)
查找使用缓冲的任何模块,并有选择地禁用它。
我在CentOS 4.8上运行PHP 5.3.5,在这之后我发现eaccelerator需要升级。
答案 11 :(得分:2)
我在我拥有的服务器上也遇到过这个问题,根本原因是APC。我在php.ini文件中注释掉了“apc.so”扩展,重新加载了Apache,并且网站重新启动了。
答案 12 :(得分:2)
我已经尝试了以上所有内容和zend.enable_gc = 0
- 唯一的配置设置,这对我有帮助。
PHP 5.3.10-1ubuntu3.2与Suhosin-Patch(cli)(内置:2012年6月13日17:19:58)
答案 13 :(得分:2)
我认为很多原因都可能导致这个问题。在我的例子中,我将2个类命名为同一个名称,并且一个将尝试加载另一个类。
class A {} // in file a.php
class A // in file b.php
{
public function foo() { // load a.php }
}
在我的案例中它会导致这个问题。
(使用laravel框架,运行php artisan db:seed in real)
答案 14 :(得分:2)
我使用PHP的Mongo 2.2驱动程序出现此错误:
$collection = $db->selectCollection('post');
$collection->ensureIndex(array('someField', 'someOtherField', 'yetAnotherField'));
^^不工作
$collection = $db->selectCollection('post');
$collection->ensureIndex(array('someField', 'someOtherField'));
$collection->ensureIndex(array('yetAnotherField'));
^^工作! (?!)
答案 15 :(得分:2)
在PHP 5.3上,经过多次搜索,这是对我有用的解决方案:
我为此页添加了disabled the PHP garbage collection:
<? gc_disable(); ?>
到问题页面的末尾,这使得所有错误都消失了。
答案 16 :(得分:1)
我遇到了同样的问题,当我的memcached会话的session.save_path的IP不正确时。将其更改为正确的IP修复了问题。
答案 17 :(得分:1)
如果您正在使用特征并且在课程之后加载特征(即自动加载的情况),您需要事先加载特征。
https://bugs.php.net/bug.php?id=62339
注意:这个bug非常随机;由于它的性质。
答案 18 :(得分:1)
对我来说问题是使用pdo_mysql。查询返回1960年的结果。我试图返回1900条记录并且有效。所以问题是pdo_mysql和太大的数组。我用原始的mysql扩展重写了查询并且它有效。
$link = mysql_connect('localhost', 'user', 'xxxx') or die(mysql_error());
mysql_select_db("db", $link);
Apache没有报告任何先前的错误。
zend_mm_heap corrupted
zend_mm_heap corrupted
zend_mm_heap corrupted
[Mon Jul 30 09:23:49 2012] [notice] child pid 8662 exit signal Segmentation fault (11)
[Mon Jul 30 09:23:50 2012] [notice] child pid 8663 exit signal Segmentation fault (11)
[Mon Jul 30 09:23:54 2012] [notice] child pid 8666 exit signal Segmentation fault (11)
[Mon Jul 30 09:23:55 2012] [notice] child pid 8670 exit signal Segmentation fault (11)
答案 19 :(得分:1)
“zend_mm_heap corrupted”表示内存管理问题。可以由任何PHP模块引起。 在我的情况下安装APC解决了。理论上,其他软件包如eAccelerator,XDebug等也可能有所帮助。或者,如果您安装了这种模块,请尝试将其关闭。
答案 20 :(得分:1)
我正在写一个php扩展,也遇到了这个问题。当我从我的扩展名调用具有复杂参数的extern函数时,会弹出此错误。
原因是我没有在extern函数中为参数(char *)分配内存。如果您正在撰写相同类型的扩展名,请注意这一点。
答案 21 :(得分:0)
很多人提到禁用XDebug来解决该问题。在很多情况下,这显然是不可行的,因为启用它是有原因的-调试代码。
我遇到了同样的问题,并注意到,如果我停止在IDE(PhpStorm 2019.1 EAP)中侦听XDebug连接,则会停止发生错误。
对我来说,实际的解决方法是删除所有现有的断点。
这可能是有效的解决方法,PhpStorm有时不能很好地删除断点,这些断点不再在外部更改文件(例如,通过git)后引用有效的代码行
编辑: 在xdebug问题跟踪器中找到了相应的错误报告: https://bugs.xdebug.org/view.php?id=1647
答案 22 :(得分:0)
这里的许多答案都很陈旧。对我来说(php 7.0.10通过Ondrej Sury&ucntu 14.04 和 16.04的PPA),问题似乎在于APC。我使用apc_fetch()等缓存了数百个小数据,当缓存一大块缓存时,我得到了错误。解决方法是切换到基于文件系统的缓存。
关于github https://github.com/oerdnj/deb.sury.org/issues/452#issuecomment-245475283的更多细节。
答案 23 :(得分:0)
如果有人以与我相同的方式解决这个问题,我想我会提供适合我的解决方案。
我在Windows上安装了php
以外的驱动器( H:)。
在我的php.ini文件中,几个不同的文件系统变量的值被写成\path\to\directory
- 如果我的安装在C:
上,它将正常工作。
我需要将值更改为H:\path\to\directory
。在我的php.ini
文件中添加驱动器号的几个不同位置可以立即解决问题。我也确定(尽管我认为没有必要)在我的PEAR config
中解决同样的问题 - 因为几个变量值也排除了那里的驱动器号。
答案 24 :(得分:0)
真正通过代码搜索无声错误。在我的Symfony应用程序中,从树枝基本模板中删除块后,我得到了zend_mm_heap损坏的错误,而不记得它是在子模板中引用的。没有抛出任何错误。
答案 25 :(得分:0)
在已升级到jessie的Debian服务器上有zend_mm_heap corrupted
和child pid ... exit signal Segmentation fault
。经过长时间的调查后发现,在Zend-Engine普遍可用之前就安装了XCache。
在apt-get remove php5-xcache
和service apache2 restart
后,错误消失了。
答案 26 :(得分:0)
我在本地开发中遇到了这个问题,同时使用 docker 和 php 的内置开发服务器和 Craft CMS。
我的解决方案是在 Craft 的会话中使用 Redis。
PHP 7.4
答案 27 :(得分:0)
上面已经编写了此选项,但我想带您逐步了解如何重现此错误。
简而言之。它帮助了我:
opcache.fast_shutdown = 0
我的旧配置:
逐步:
phpinfo()
opcache_reset()
(感谢bug report,注释[2015-05-15 09:23 UTC] nax_hh at hotmail dot com
)。在您的网站上加载多个页面。如果要归咎于OPcache,那么在nginx日志中将出现带有文本的行104:对等连接重置
以及php-fpm日志中
zend_mm_heap损坏
然后在下一行
fpm_children_bury()
opcache.fast_shutdown=0
(在/etc/php.d/opcache.ini
文件中为我设置)service php-fpm restart
)opcache_reset()
并再次加载一些页面。现在应该没有错误。顺便说一句。在phpinfo()
的输出中,您可以找到OPcache的统计信息,然后优化参数(例如,增加内存限制)。 Good instructions用于调整opcache(俄语,但您可以使用翻译器)
答案 28 :(得分:0)
zend_mm_heap损坏的问题使我困惑了大约两个小时。首先,我禁用并删除了memcached,尝试了该问题的答案中提到的某些设置,并且在测试之后,这似乎与OPcache设置有关。我禁用了OPcache,问题消失了。之后,我重新启用了OPcache,对我来说
core notice: child pid exit signal Segmentation fault
和
zend_mm_heap corrupted
显然可以通过更改
解决/etc/php.d/10-opcache.ini
我包括了在这里更改的设置; opcache.revalidate_freq = 2值得一提,我没有更改该值。
opcache.enable=1
opcache.enable_cli=0
opcache.fast_shutdown=0
opcache.memory_consumption=1024
opcache.interned_strings_buffer=128
opcache.max_accelerated_files=60000
答案 29 :(得分:0)
对我来说,是ZendDebugger导致内存泄漏并使MemoryManager崩溃。
我禁用了它,我正在寻找更新的版本。如果我找不到一个,我将切换到xdebug ...
答案 30 :(得分:0)
2014年11月13日PHP中修复了一个错误:
修复了错误#68365(在zend_hash_copy内存溢出后zend_mm_heap已损坏。)
在版本5.4.35,5.5.19和5.6.3中进行了更新。在我的情况下,当我从使用Ubuntu的官方可信包(5.5.9 + dfsg-1ubuntu4.14)改为由Ondrej Sury打包的5.5.30版本时,问题就消失了。没有其他解决方案适合我,我不想禁用opcache或抑制错误,因为这确实导致了段错误(500响应)。
Ubuntu 14.04 LTS:
export LANG=C.UTF-8 # May not be required on your system
add-apt-repository ondrej/php5
apt-get update
apt-get upgrade
答案 31 :(得分:0)
对我来说,是带有Xdebug的RabbitMq进入PHPStorm,所以&gt;设置/语言和框架/ PHP / Debug / Xdebug&gt;解开&#34;可以接受外部连接&#34;。
答案 32 :(得分:0)
我在这里的情况相同,上面没有任何帮助,并且更严肃地检查我发现我的问题,它包括在发送一些输出到缓冲区后尝试做死(header()),在代码中执行此操作的人忘了关于CakePHP资源并没有做出简单的“返回$ this-&gt;重定向($ url)”。
试图重新发明井,这就是问题所在。
我希望这有助于帮助某人!
答案 33 :(得分:0)
可能有助于某些人的一些提示
fedora 20,php 5.5.18
public function testRead() {
$ri = new MediaItemReader(self::getMongoColl('Media'));
foreach ($ri->dataReader(10) as $data) {
// ...
}
}
public function dataReader($numOfItems) {
$cursor = $this->getStorage()->find()->limit($numOfItems);
// here is the first place where "zend_mm_heap corrupted" error occurred
// var_dump() inside foreach-loop and generator
var_dump($cursor);
foreach ($cursor as $data) {
// ...
// and this is the second place where "zend_mm_heap corrupted" error occurred
$data['Geo'] = [
// try to access [0] index that is absent in ['Geo']
'lon' => $data['Geo'][0],
'lat' => $data['Geo'][1]
];
// ...
// Generator is used !!!
yield $data;
}
}
使用var_dummp()实际上不是错误,它只是用于调试,将在生产代码中删除。但是发生zend_mm_heap的真正地方是第二位。
答案 34 :(得分:0)
由于没有其他答案解决它,我在php 5.4中遇到了这个问题,当我意外地运行了一个无限循环。
答案 35 :(得分:0)
对我来说问题是崩溃的memcached守护进程,因为PHP被配置为在memcached中存储会话信息。它正在吃100%的CPU,表现得很奇怪。 memcached启动后问题已经消失。
答案 36 :(得分:0)
在运行使用'&amp;'的旧代码时,我也注意到了这个错误和SIGSEGV在PHP 5.2 +中运行它时显式强制引用。
答案 37 :(得分:0)
设置
assert.active = 0
php.ini中的帮助了我(它关闭了php5UTF8
库中的类型断言,zend_mm_heap corrupted
消失了)
答案 38 :(得分:0)
在我的情况下,我忘了在代码中跟随:
);
我在这里和那里的代码中玩过并忘了它 - 在某些地方我有堆腐败,有些情况只是简单的'段错误:
[Wed Jun 08 17:23:21 2011] [notice] child pid 5720 exit signal Segmentation fault (11)
我在mac 10.6.7和xampp。
答案 39 :(得分:0)
因为我从未找到解决方案,所以我决定升级我的LAMP环境。我用PHP 5.3.x去了Ubuntu 10.4 LTS。这似乎已经为我解决了这个问题。