大き過ぎるXMLファイルをPHPのバッチで解析する
やりたいこと
WebAPI リクエストで得られる XML ファイルを解析する。PHP で XML を解析するならば、XML_Unserializer を使えば簡単なわけです。今回、データが大き過ぎるXMLファイルを解析したい、それも、バッチで一括処理したい、という用があって、困ってしまった。
問題点
memory_limit を 500MB まで上げた状態でも、メモリが足りないという実行時エラーになってしまう。一般に、パーサを通すと元ファイルの4倍くらいのメモリを食う。
基礎知識
- 組み込み関数 memory_get_usage でデバッグログすることで、メモリの使用状況を把握し、食っている箇所を突き止める。
- gc を促すには unset という手段があります。とはいえ、これは実行環境依存なので、unset しても解放されないケースはある。XML_Unserializer の場合、unset が効かないというか、パーサライブラリ内部の方でリークしているのではないか、と思われる挙動だった。
- PHP5のgcはリファレンスカウンタらしいので、循環参照があるとリークする。
- 省メモリなライブラリとして XMLReader というパーサもあるけれど、こちらはプログラムがしんどくなりそう。