しろあじ備忘録

システム関係の備忘録。ザルのような記憶力なので、こうして書いておかないと忘れるのだよ。

【PHP】PHP のメモリーリークで学んだ教訓

モリーエラー発生

PHP 5.2のお話なので、
結局、PHPを古いまま使うな、という話なんですが。

メイン開発環境とは別に、
ウン万件のデータを処理するプログラムをPHPでコーディング。
大量のデータなもので、ほかの人の開発に影響がない

ちょうど、程よいデータが入っているマシンがあったので、
他に誰も使っていないその環境を使った。PHPのバージョンを気にしなかった。


ところが、1万件も満たないところで、
モリー負荷エラーが出て処理が終わってしまう。

例のこれですね。
 Allowed memory size of 134217728 bytes exhausted

メイン環境では10万件余裕だったのに。。

一体どこで無駄にメモリ消費してるのか

その処理はDB参照したり、
csv見たり、
さらに別の配列をネストで回したり、、

一見、怪しい箇所は多々あった。

なので、そういった個所に、

<?php
echo microtime(true)."<br>";
echo memory_get_usage(true)."<br>";
?>

を速攻でいれて試した。

が、なかなか「ここ!」が絞り切れない。

さらに、細かく上記のコードを入れたら、
あれ?これ?

<?php
$date1 = new DateTime();
?>

結局今回はDateTimeオブジェクト

とりあえず unsetを入れてみたが改善されず。

ネットで調べまくったわけです。

「DateTime メモリー PHP」といった検索したけど、めぼしいのが見つからず、、。


結局、英語ページを探しまくり、
PHP :: Bug #47351 :: [PATCH] Memory leak in DateTime
を見つけた。


PHP5.2.11より前は、 new DateTime();するたびにメモリーリークだとか。


え、この環境のPHPって何なの?と調べたら、
PHP5.2.11より前だったわけです。

後ほど、メインマシン(PHP5.6)を借りて実行したら
モリーリーク問題は解決しているので、
問題なく処理ができた。

なんだ、最初にPHPバージョンに着目すればよかったな。

というのが、その時の教訓。

調べるのに半日以上使っちゃったよ。。もったいない。

とはいえ、こういう経験の積み重ねだよねえ。開発は。

新しいクラスには注意したほうが良いかもね

DateTimeクラスって、PHP5.2で登場したんだね。
なので、登場してしばらくは、メモリーリークというバグを抱えていたということか。

どんな言語でも、こういった新しいクラス、オブジェクト、など、がバージョンアップ時に登場した場合、
一見、とても便利そう!と飛びつきたくはなるが、
こういった「まだバグが潜んでいる」という視点は持っていたほうがよいなあ。

f:id:ramapipi:20171103110809j:plain