致命的エラー「許容メモリサイズを使い果たしました」から回復する方法
-
22-09-2019 - |
質問
PHP の致命的なエラーから回復するための解決策をご存知ですか:」許容メモリサイズ ...疲れ果てた"
致命的なエラーが発生したときに呼び出されるシャットダウン関数があります。この関数は、そこから ErrorException を作成し、ログに記録します。
問題は :利用可能なメモリがなくなると、エラーをログに記録できません (私は Zend Framework を使用して FirePHP 経由で Firebug にログインします)。
それで、私が言いたいのは「」そこからどうやって回復するか「基本的なエラー ログを実行し、Zend Framework にヘッダーを送信させて、エラーが他のエラーとして (私の場合は Firebug に) 記録されるようにする方法は何ですか?」
ありがとう
解決
このエラーは致命的なエラーです。 PHPはそれのメモリ制限をヒットした場合、それはあなたの例外とそれはその実行を続けていく必要があり、他のメモリを作成するために、任意のより多くのメモリを割り当てることができなくなります。
エラーの別のタイプがあります - その名が示唆するように「キャッチ可能な致命的なエラー」は、のtry / catchに巻き込まれ、残念ながらメモリサイズの割り当ては、そのうちの一つではないことができます。
。他のヒント
if((memory_get_usage() / 1024 /1024) < 70)
は、私は単に「70」の「通常」メガバイトの値と比較するために二乗1024 memory_get_usageを分割します。
私は、forループ内でのPHPとメモリの問題に遭遇したと致命的なエラーをオフに設定するから私のスクリプトを防ぐために、文の場合は、このシンプルなを書きました。また、私が上で動作していたサーバーが(これはしばしばopenshiftまたはDreamhostのような大規模なWebホストのようないくつかのクラウドの提供の場合である。)私は、メモリの制限を変更することはできませんでした私は本当に(深刻な性能劣化に気付きませんでした若干異なるPHP 4.xまたは5.xのより...任意の割合で致命的なエラーを与えて、スクリプトのパフォーマンス含意は、関数呼び出しが強制することが任意のオーバーヘッドを上回るいるこのようなことがあり、ハンドル機能PHP 5.3インチとなりも防ぎますすべての利用可能なRAMを消費するから暴走スクリプトます。
多くが主張すること。ああ、ちょっとお使いのソフトウェアが最適化されていません。はい。あなたはおそらく正しいです。あなたはそれでより多くのメモリをスローする必要がある前に、しかし、複雑なデータセットであなただけそんなにパフォーマンスを絞り出すことができます。そして、Ajaxのフローでメモリエラーダウン狩りは非常にイライラすることができます。特にあなたが必ずあなたのログファイルがどこにいないときます。
エラー処理をカスタマイズする通常の方法は、
set_error_handler
— ユーザー定義のエラーハンドラー関数を設定します。
この関数のドキュメントには次のように書かれています (私の強調):
次のエラー タイプは、ユーザー定義関数では処理できません。 E_エラー, 、E_PARSE、E_CORE_ERROR、E_CORE_WARNING、E_COMPILE_ERROR、E_COMPILE_WARNING、および set_error_handler() が呼び出されるファイルで発生する E_STRICT のほとんど。
したがって、定期的には機能しませんが、試してみることはできます
PHP7 では、エラーと例外は Throwable であるため、それらを試したりキャッチしたりできます。
PHPエラーはApacheのエラーログ/path/to/apache/logs/error.log
にデフォルトで送信され、あなたはそこにそれを見ることができます。
テストされていないトリックのためのアイデアを持って、私はそれが助けたかどうかを知るために幸せになると思います。あなたが最初にシャットダウン機能を登録し、シャットダウン機能のコードが最初に実行されたときにそれを解放するいくつかのグローバル変数を割り当てます。その後、Exceptionオブジェクトを作成するための十分なメモリを有していてもよいです。それが働いたと、ここでのコードを公開してください場合は、私に教えてくださいます。
私のためにこの加工した細かいます:
try {
ini_set('memory_limit', (ini_get('memory_limit')+1).'M');
} catch(Exception $e) {}
これはあなたのメモリ制限がフォーマット123M
であると仮定します。
私は考えることができる一つは、あなたが手動で定期的にクエリmemory_get_usage()
(例えば、すべてのループの繰り返しを)あなたのメモリ集約型の操作を行うと、それはいくつかのフェールセーフ値の上になった時、あなたのヘッダ/エラーをダンプしているときということですスクリプト限界以下。それは多くのダウンスクリプトが遅くなりますが、少なくとも、あなたが何かのバックを取得します。
それとも、あなたが幹部を使用して、Webベースのものの中から呼び出されるCLIベースのスクリプトとしてメモリ集約ものを実行し、これを実行することができないかもしれません。 CLI部分が倒れるかもしれないが、Webパーツは、それを報告することができるようになります。