0

PHP メモリ内に循環参照でいっぱいのかなり大きなグラフがあります。グラフ全体をシリアル化して、リクエストの間に保存していました。PHP5.3 では問題なく動作しましたが、PHP5.5 にアップグレードしたところ、奇妙なことが起こっています。

PHP / Apache がシリアル化中に突然クラッシュ/終了し、ChromeERR_CONNECTION_RESETが表示される PHP ログにエラーはなく、デバッグ モードの Apache ログにも何もありません。

かなりのデバッグを行った後、グラフを少し小さくしても機能することに気付きました。ただし、データを少しずつ元に戻すと、再導入すると失敗する非常に特定のポイントがあります。その特定のポイントをスキップして、代わりに他のデータを導入しても、続行できます。

メモリの問題ではない

私は非常に高いメモリ制限を設定しました: memory_limit = 2048M、クラッシュするデータを導入する直前に、memory_get_usage()26M とmemory_get_peak_usage()41M を与えるので、十分に残っています。

時間の問題ではない

タイムアウト設定の範囲内であるため、おそらく時間に関連するものではなく、クラッシュすると、実際には、最後の作業シリアライゼーションを完了するのにかかった時間よりも早くクラッシュします。

循環参照/ループが多すぎますか?

クラッシュの原因となる私が紹介するデータは、オブジェクトに関して特別なことは何もしません。これはすべて同じ種類の PHP オブジェクトです (簡単にするためにノードとエッジを使用しています)。また、私が紹介するオブジェクトを直接取り巻く関係は、私に奇妙なことを何も教えてくれません。私が考えていることの1つは、シリアライズアルゴリズムがすべてのオブジェクトの変更を通過する方法で「問題のある」データが導入されると、トラバーサルパスが変更され、何かがクラッシュする原因になるということです.

他の上限?

私が考えることができるもう1つのことは、私が到達している他の上限があるということです. つまり、クラッシュを引き起こさずに元に戻すことができない「問題のある」データを見つけたら、最初に他の部分をオフにすると、データを元に戻すことができます。したがって、それはデータをまったく指していないようです。しかし、どの制限ですか?絞り出すことができた文字列の最大長は 5.517.365 文字で、mb_strlen($string, '8bit'). しかし、文字列が約 400 万文字になる場合があり、少し追加するとクラッシュします。それは、その小さなデータがグラフのより深い/より大きな部分をより早くシリアル化する原因となり、内部的に何かの同じ上限に達したことを意味する可能性がありますか?

serialize() はバッファや tmp ファイルのようなものを使用しますか? それとも、単に「プレーン メモリ」を使用する必要がありますか?

私がヒットしている可能性のある他の境界線はありますか?および/またはどの設定がそれを解決する可能性がありますか?

4

0 に答える 0