突然、アプリケーションでこれまでにない問題が発生しました。Apacheのエラーログを確認することにしましたが、「zend_mm_heapが破損しています」というエラーメッセージが見つかりました。これは何を意味するのでしょうか。
OS:Fedora Core 8 Apache:2.2.9 PHP:5.2.6
突然、アプリケーションでこれまでにない問題が発生しました。Apacheのエラーログを確認することにしましたが、「zend_mm_heapが破損しています」というエラーメッセージが見つかりました。これは何を意味するのでしょうか。
OS:Fedora Core 8 Apache:2.2.9 PHP:5.2.6
output_buffering
多くの試行錯誤の末、 php.iniファイルの値を増やすと、このエラーがなくなることがわかりました。
これは、構成オプションを変更することで必ずしも解決できる問題ではありません。
構成オプションを変更すると、プラスの影響が出る場合がありますが、同じように簡単に事態を悪化させたり、まったく何もしなかったりする可能性があります。
エラーの性質は次のとおりです。
#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を使用)、実行時にプログラムが使用できるメモリの領域を指します。
ひどいコードをいじってみると、明らかに正しくないステートメントのすべてがセグメンテーション違反(致命的な終了エラー)を引き起こすわけではないことがわかります。
サンプルコードでこれらのエラーを明示的に作成しましたが、同じ種類のエラーはメモリ管理環境で非常に簡単に発生します。たとえば、一部のコードが変数(または他のシンボル)のrefcountを正しい方法で維持しない場合解放するのが早すぎると、すでに解放されているメモリから別のコードが読み取られ、アドレスが間違って格納されている場合、別のコードが無効なメモリに書き込まれ、2回解放される可能性があります...
これらはPHPでデバッグできる問題ではなく、内部開発者の注意が絶対に必要です。
行動方針は次のとおりです。
利益がないかもしれません...最初に言ったように、設定をいじることで症状を変える方法を見つけることができるかもしれませんが、これは非常にヒットとミスであり、次にあなたが持っているときは役に立ちません同じzend_mm_heap corrupted
メッセージですが、構成オプションは非常に多くあります。
バグを見つけたときにバグレポートを作成することは非常に重要です。次にバグを見つけた人がそれを実行するとは限りません...おそらく、実際の解決策は決して不思議ではありません。問題を認識している適切な人々。
環境に設定USE_ZEND_ALLOC=0
すると、Zend自身のメモリマネージャーが無効になります。Zendのメモリマネージャは、各リクエストに独自のヒープがあり、リクエストの最後にすべてのメモリが解放され、PHPに最適なサイズのメモリのチャンクが割り当てられるように最適化されていることを確認します。
これを無効にすると、これらの最適化が無効になります。さらに重要なことに、リクエストの最後にZend MMに依存してメモリを解放する拡張コードが多数あるため、メモリリークが発生する可能性があります(tut、tut)。
症状を隠すこともできますが、システムヒープはZendのヒープとまったく同じ方法で破損する可能性があります。
耐性が高いか低いように見えるかもしれませんが、問題の根本的な原因を修正することはできません。
それをまったく無効にする機能は、内部開発者の利益のためです。ZendMMを無効にしてPHPをデプロイしないでください。
PHP 5.5でも同じエラーが発生し、出力バッファリングを増やしても効果がありませんでした。私もAPCを実行していなかったので、それは問題ではありませんでした。私は最終的にそれをopcacheまで追跡しました、私は単にそれをCLIから無効にする必要がありました。これには特定の設定がありました。
opcache.enable_cli=0
切り替えると、zend_mm_heapの破損エラーはなくなりました。
Linuxボックスを使用している場合は、コマンドラインでこれを試してください
export USE_ZEND_ALLOC=0
を確認してくださいunset()
。デストラクタ内の(または同等の)unset()
参照がないこと、およびデストラクタ内のsによって同じオブジェクトへの参照カウントが0に低下しないことを確認してください。いくつかの調査を行ったところ、これが通常ヒープの原因であることがわかりました。腐敗。$this
unset()
zend_mm_heap破損エラーに関するPHPバグレポートがあります。[2011-08-31 07:49 UTC] f dot ardelian at gmail dot com
それを再現する方法の例については、コメントを参照してください。
php.ini
他のすべての「解決策」(変更、より少ないモジュールでソースからPHPをコンパイルするなど)は、問題を隠しているだけだと感じています。
私にとっては、試してみるまで、これまでの答えはどれもうまくいきませんでした。
opcache.fast_shutdown=0
これまでのところうまくいくようです。
PHP5.6とPHP-FPMおよびApacheproxy_fcgiを使用していますが、それが重要な場合は...
私の場合、このエラーの原因は、アレイの1つが非常に大きくなっていることでした。反復ごとに配列をリセットするようにスクリプトを設定しましたが、これで問題が解決しました。
バグトラッカーに従って、を設定しopcache.fast_shutdown=0
ます。高速シャットダウンは、Zendメモリマネージャーを使用してその混乱をクリーンアップします。これにより、それが無効になります。
ここに答えは1つではないと思うので、私の経験を追加します。私はこれと同じエラーをランダムなhttpdsegfaultsと一緒に見ました。これはcPanelサーバーでした。問題の症状は、apacheがランダムに接続をリセットすることでした(chromeでデータが受信されなかったか、Firefoxで接続がリセットされました)。これらは一見ランダムに見えました-ほとんどの場合は機能しましたが、機能しない場合もありました。
シーンに到着したとき、出力バッファリングはオフでした。出力バッファリングを示唆するこのスレッドを読むことで、何が起こるかを確認するためにオン(= 4096)にしました。この時点で、それらはすべてエラーを表示し始めました。エラーが繰り返し可能になったので、これは良かったです。
私は通り抜けて、拡張機能を無効にし始めました。その中には、eaccellerator、pdo、ioncube loader、そして疑わしいと思われるものがたくさんありましたが、どれも役に立ちませんでした。
私はついに、いたずらなPHP拡張機能を「homeloader.so」として見つけました。これは、ある種のcPanel-easy-installerモジュールのようです。削除後、他の問題は発生していません。
その点で、これは一般的なエラーメッセージであるように思われるため、マイレージはこれらすべての回答によって異なります。実行できる最善の行動は次のとおりです。
上記のすべてに失敗した場合は、次のようなことも試すことができます。
幸運を。
私はこの問題に一週間取り組んだ、これは私のために働いた、または少なくともそう思われる
これら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秒かかったことを発見しました。私はこのテストをかなりの回数、そして毎回同じように実行しました。毎回新しいオブジェクトを作成するのではなく(ここには長いループがあります)、オブジェクトを再利用する必要があると思いました。これまでにスクリプトを12回以上テストしましたが、メモリエラーはなくなりました。
バッファリングを使用するモジュールを探し、選択的に無効にします。
CentOS4.8でPHP5.3.5を実行していますが、これを実行した後、eacceleratorをアップグレードする必要があることがわかりました。
私が所有するサーバーでもこの問題が発生しました。根本的な原因はAPCでした。php.iniファイルの「apc.so」拡張子をコメントアウトし、Apacheをリロードすると、サイトがすぐに復旧しました。
私は上記のすべてを試しました-そしてzend.enable_gc = 0
-私を助けた唯一の設定設定。
PHP 5.3.10-1ubuntu3.2 with Suhosin-Patch(cli)(ビルド:2012年6月13日17:19:58)
PHP用のMongo2.2ドライバーを使用すると、次のエラーが発生しました。
$collection = $db->selectCollection('post');
$collection->ensureIndex(array('someField', 'someOtherField', 'yetAnotherField'));
^^動作しません
$collection = $db->selectCollection('post');
$collection->ensureIndex(array('someField', 'someOtherField'));
$collection->ensureIndex(array('yetAnotherField'));
^^動作します!(?!)
PHP 5.3では、多くの検索を行った後、これが私にとって有効なソリューションです。
次を追加して、このページのPHPガベージコレクションを無効にしました。
<? gc_disable(); ?>
問題のあるページの最後まで、すべてのエラーが消えました。
ソース。
多くの理由がこの問題を引き起こす可能性があると思います。そして私の場合、私は2つのクラスに同じ名前を付け、1つは別のクラスをロードしようとします。
class A {} // in file a.php
class A // in file b.php
{
public function foo() { // load a.php }
}
そしてそれは私の場合この問題を引き起こします。
(laravelフレームワークを使用して、php artisan db:seedを実際に実行します)
私にとって問題は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)
これと同じ問題が発生し、memcachedセッションのsession.save_pathのIPが正しくない場合に発生しました。正しいIPに変更すると、問題が修正されました。
トレイトを使用していて、クラスの後にトレイトがロードされる場合(つまり、自動ロードの場合)、事前にトレイトをロードする必要があります。
https://bugs.php.net/bug.php?id=62339
注:このバグは非常にランダムです。その性質のため。
「zend_mm_heapが破損している」とは、メモリ管理に問題があることを意味します。PHPモジュールが原因である可能性があります。私の場合、APCのインストールはうまくいきました。理論的には、eAccelerator、XDebugなどの他のパッケージも役立つ可能性があります。または、そのようなモジュールがインストールされている場合は、それらをオフにしてみてください。
私はphp拡張機能を書いていますが、この問題も発生します。拡張機能から複雑なパラメータを使用してextern関数を呼び出すと、このエラーがポップアップ表示されます。
その理由は、extern関数のパラメーター(char *)にメモリーを割り当てていないためです。同じ種類の拡張機能を作成している場合は、これに注意してください。
多くの人が、問題を解決するためにXDebugを無効にすることに言及しています。これは、コードをデバッグするために有効になっているため、多くの場合、明らかに実行可能ではありません。
同じ問題が発生し、IDE(PhpStorm 2019.1 EAP)でXDebug接続のリッスンを停止すると、エラーの発生が停止したことに気付きました。
私にとっての実際の修正は、既存のブレークポイントを削除することでした。
これが有効な修正である可能性は、PhpStormが、ファイルが外部で(たとえば、gitによって)変更された後、コードの有効な行を参照しなくなったブレークポイントを削除するのが苦手な場合があることです。
編集:xdebug課題追跡システムで対応するバグレポートを見つけました: https ://bugs.xdebug.org/view.php?id = 1647
zend_mm_heapの問題により、約2時間ほどボッゲルが発生しました。まず、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
また、PHP 5.2以降で実行しているときに、「&」を使用して明示的に参照を強制する古いコードを実行すると、このエラーとSIGSEGVが発生することに気付きました。
私にとって、メモリリークを引き起こし、MemoryManagerをクラッシュさせたのはZendDebuggerでした。
私はそれを無効にしました、そして私は現在新しいバージョンを探しています。見つからない場合は、xdebugに切り替えます...
これに対する解決策が見つからなかったため、LAMP環境をアップグレードすることにしました。PHP5.3.xを使用してUbuntu10.4LTSにアクセスしました。これは私にとって問題を止めたようです。
私の場合、コードで次のことを忘れました:
);
私は遊んで、あちこちのコードでそれを忘れました-いくつかの場所で私はヒープの破損を受け取りました、いくつかの場合は単なる古いセグメンテーション違反です:
[2011年6月8日水曜日17:23:21][通知]子pid5720終了信号セグメンテーション違反(11)
私はmac10.6.7とxamppを使用しています。
設定
assert.active = 0
php5UTF8
php.iniで私を助けてくれました(ライブラリの型アサーションをオフにしてzend_mm_heap corrupted
消えました)
PHPがセッション情報をmemcachedに保存するように構成されていたため、私にとっては問題はmemcachedデーモンのクラッシュでした。それは100%CPUを食べていて、変な振る舞いをしていました。memcachedの再起動の問題がなくなった後。
他のどの回答もそれに対処していなかったので、誤って無限ループを実行したときにphp5.4でこの問題が発生しました。
誰かを助けるかもしれないヒントのいくつか
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が発生した実際の場所は2番目の場所です。
私はここでも同じ状況にあり、上記のことは何も役に立ちませんでした。もっと真剣にチェックすると、問題が見つかりました。バッファに出力を送信した後、try do die(header())で構成されています。コードでこれを行った人は、CakePHPリソースを忘れていました。単純な「return$this-> redirect($ url)」は作成しませんでした。
井戸を再発明しようとして、これが問題でした。
私はこれが誰かを助けることを願っています!
私にとっては、PHPStormへのXdebugを備えたRabbitMqだったので、>設定/言語とフレームワーク/PHP/デバッグ/Xdebug>「外部接続を受け入れることができます」のチェックを外します。
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バージョンに変更すると、問題は解決しました。他の解決策はどれも私にはうまくいきませんでした。これが実際にsegfaults(500応答)を引き起こしていたので、opcacheを無効にしたりエラーを抑制したりしたくありませんでした。
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
他の誰かが私と同じようにこの問題を抱えているという偶然の機会に、私は私のために働いた解決策を提供すると思いました。
システムドライブ( H:)php
以外のドライブのWindowsにインストールしました。
私のphp.iniファイルでは、いくつかの異なるファイルシステム変数の値が次のように記述され \path\to\directory
ていました。これは、インストールがオンの場合は正常に機能しC:
ます。
値をに変更する必要がありましたH:\path\to\directory
。ファイルのいくつかの異なる場所にドライブ文字を追加するとphp.ini
、問題がすぐに修正されました。また、同じ問題を修正することも確認しました(ただし、これは必要ではないと思います)PEAR config
。いくつかの変数値によって、ドライブ文字も除外されたためです。
ここでの答えの多くは古いものです。私にとって(ubuntu14.04と16.04のOndrejSuryのPPAを介したphp7.0.10)、問題はAPCにあるように見えます。apc_fetch()などを使用して数百の小さなデータをキャッシュしていましたが、キャッシュのチャンクを無効にするとエラーが発生しました。回避策は、ファイルシステムベースのキャッシュに切り替えることでした。
githubの詳細https://github.com/oerdnj/deb.sury.org/issues/452#issuecomment-245475283。
サイレントエラーがないか、コードを実際に調べてください。私のSymfonyアプリでは、サブテンプレートで参照されていることを覚えていない小枝ベーステンプレートからブロックを削除した後、zend_mm_heap破損エラーが発生しました。エラーはスローされませんでした。
jessieにアップグレードされたDebianサーバーでzend_mm_heap corrupted
一緒にいました。child pid ... exit signal Segmentation fault
長い調査の結果、Zend-Engineが一般的に利用可能になる前にXCacheがインストールされていたことが判明しました。
その後apt-get remove php5-xcache
、service apache2 restart
エラーは消えました。
このオプションはすでに上に書かれていますが、このエラーを再現する手順を説明したいと思います。
簡単に言えば。それは私を助けました:
opcache.fast_shutdown = 0
私のレガシー構成:
ステップバイステップ:
phpinfo()
opcache_reset()
に感謝します)。サイトに複数のページを読み込みます。OPcacheが原因である場合、nginxログにテキストの行が表示されます[2015-05-15 09:23 UTC] nax_hh at hotmail dot com
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の統計を見つけて、パラメータを最適化できます(たとえば、メモリ制限を増やします)。opcacheを調整するための良い指示(ロシア語ですが、翻訳者を使用できます)
Docker&phpの組み込み開発サーバーをCraft CMSで使用しているときに、ローカル開発でこの問題が発生しました。
私の解決策は、CraftのセッションにRedisを使用することでした。
PHP 7.4