当前位置:  开发笔记 > 编程语言 > 正文

"zend_mm_heap corrupted"是什么意思

如何解决《"zend_mm_heapcorrupted"是什么意思》经验,为你挑选了8个好方法。

突然之间,我的应用程序出现了问题,这是我以前从未遇到的问题.我决定检查Apache的错误日志,我发现一条错误消息"zend_mm_heap corrupted".这是什么意思.

操作系统:Fedora Core 8 Apache:2.2.9 PHP:5.2.6



1> 小智..:

经过多次试验和错误,我发现如果我增加output_bufferingphp.ini文件中的值,这个错误就会消失


增加什么?为什么这个改变会使这个错误消失?
@andrewtweber我知道ob是什么,我想知道dsmithers回答中遗漏的具体细节,因为我有与op相同的错误信息.关闭:原来我的问题是与memcached相关的配置错误.不过谢谢!
@KyleCronin我们的服务平台在生产中使用Memcache.但是,某些单个实例 - 非生产/沙箱,客户一次性 - 不使用内存缓存.在后一种情况下,我将配置从生产复制到客户一次性,并且memcache配置指示了在该环境中不可用的memcache服务器URI.我在应用程序中删除了行并禁用了memcache,问题就消失了.因此,长话短说,在特定环境中遇到的非常具体的问题,可能通常不适用.但是,既然你问过......
即使关闭输出缓冲区,我也会收到此错误
@JDS这个答案有助于解释什么是output_buffering以及为什么增加它可以帮助http://stackoverflow.com/a/2832179/704803

2> 小智..:

我在PHP 5.5下得到了同样的错误,增加输出缓冲没有帮助.我没有运行APC,所以这不是问题.我终于将其追踪到opcache,我只需要从cli中禁用它.有一个特定的设置:

opcache.enable_cli=0

切换后,zend_mm_heap损坏的错误就消失了.


我相信你知道cli是php的命令行版本,它与用于apache web服务器的php模块无关,我很好奇如何使用cli禁用opcache有帮助吗?(我假设这发生在Web服务器上)
这篇文章的巨额加1.我们尝试了一切,但最终,只有这个工作.

3> Joe Watkins..:

这不是通过更改配置选项必须解决的问题.

更改配置选项有时会产生积极影响,但它可以轻松地使事情变得更糟,或者根本不做任何事情.

错误的本质是这样的:

#include 
#include 
#include 

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中调试的问题,它们绝对需要内部开发人员的注意.

行动方针应该是:

    在http://bugs.php.net上打开错误报告

    如果您有段错误,请尝试提供回溯

    包括尽可能多的配置信息,特别是如果您使用opcache包括优化级别.

    继续检查错误报告以获取更新,可能会要求提供更多信息.

    如果加载了opcache,请禁用优化

    我不是在选择opcache,它很棒,但已知其中一些优化会导致错误.

    如果这不起作用,即使您的代码可能较慢,请先尝试卸载opcache.

    如果其中任何一项更改或修复了问题,请更新您所做的错误报告.

    一次禁用所有不必要的扩展.

    开始单独启用所有扩展,在每次配置更改后进行彻底测试.

    如果您发现问题扩展,请使用更多信息更新您的错误报告.

    利润.

可能没有任何利润...我在开始时说过,你可能会找到一种通过搞乱配置来改变症状的方法,但这是非常受欢迎和错过,并且在下次你有时没有帮助相同的zend_mm_heap corrupted消息,只有这么多的配置选项.

当我们发现错误时,我们创建错误报告非常重要,我们不能假设下一个遇到错误的人会去做...更可能的是,实际的解决方案绝不是神秘的,如果你做的话合适的人知道这个问题.

USE_ZEND_ALLOC

如果你USE_ZEND_ALLOC=0在环境中设置,这将禁用Zend自己的内存管理器; Zend的内存管理器确保每个请求都有自己的堆,所有内存在请求结束时都是空闲的,并且针对PHP的内存大小分配进行了优化.

禁用它将禁用这些优化,更重要的是它可能会造成内存泄漏,因为有很多扩展代码依赖于Zend MM在请求结束时为它们释放内存(tut,tut).

它也可能隐藏症状,但系统堆可能会以与Zend堆完全相同的方式被破坏.

它似乎更宽容或更不宽容,但修复问题的根本原因,它不能.

完全禁用它的能力是为了内部开发人员的利益; 永远不应该在Zend MM禁用的情况下部署PHP.



4> 小智..:

如果您在Linux机器上,请在命令行上尝试此操作

export USE_ZEND_ALLOC=0



5> f.ardelian..:

检查unset()s.确保你没有unset()引用$this析构函数中的(或等价物),并且析构函数中的unset()s不会导致同一对象的引用计数降至0.我做了一些研究,发现通常会导致堆的内容腐败.

有关于zend_mm_heap损坏错误的PHP错误报告.有关[2011-08-31 07:49 UTC] f dot ardelian at gmail dot com如何重现它的示例,请参阅注释.

我有一种感觉,所有其他"解决方案"(更改php.ini,从源代码使用较少的模块编译PHP等)只是隐藏问题.


我用简单的html dom来解决这个问题,并从unset改为$ simplehtmldom-> clear()解决了我的问题,谢谢!

6> Jesús Carrer..:

对我来说,以前的答案都没有奏效,直到我尝试:

opcache.fast_shutdown=0

到目前为止似乎有效.

我正在使用PHP 5.6与PHP-FPM和Apache proxy_fcgi,如果这很重要......



7> 小智..:

在我的情况下,这个错误的原因是其中一个数组变得非常大.我已经设置了我的脚本以在每次迭代时重置数组并对问题进行排序.



8> Taco de Wolf..:

根据错误跟踪器,设置opcache.fast_shutdown=0.快速关闭使用Zend内存管理器来清理它的混乱,这会禁用它.

推荐阅读
mobiledu2402851323
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有