発端
symfonyのcommandで作ったバッチでメモリ不足発生。本番環境では発生しない。
自分にとって「またか」の現象です。その都度対策はしているので、今回は新たな原因があるのでしょう。
さっそく原因を調べていきます。調査過程は省略しますが、translatorの呼び出しで少しづつメモリが減っていることがわかりました。
追跡
translatorは普通にTranslatorInterfaceでautowireしています。
debug:autowiringコマンドで何が注入されているか見てみます。
> php bin/console debug:autowiring translator
Autowirable Services
====================
The following classes & interfaces can be used as type-hints when autowiring:
(only showing classes/interfaces matching translator)
---------------------------------------------------
Symfony\Component\Translation\TranslatorInterface
alias to translator.data_collector
---------------------------------------------------
prod環境では結果が変わることに注意です。
> php bin/console debug:autowiring translator --env=prod
Autowirable Services
====================
The following classes & interfaces can be used as type-hints when autowiring:
(only showing classes/interfaces matching translator)
---------------------------------------------------
Symfony\Component\Translation\TranslatorInterface
alias to translator.default
---------------------------------------------------
translator.data_collector, translator.defaultが実際どのクラスなのか、debug:containerコマンドで調べます。
> php bin/console debug:container translator.data_collector
Information for Service "translator.data_collector"
===================================================
---------------- -------------------------------------------------------
Option Value
---------------- -------------------------------------------------------
Service ID translator.data_collector
Class Symfony\Component\Translation\DataCollectorTranslator
(略)
> php bin/console debug:container translator.default
Information for Service "translator.default"
============================================
---------------- -------------------------------------------------------
Option Value
---------------- -------------------------------------------------------
Service ID translator.default
Class Symfony\Bundle\FrameworkBundle\Translation\Translator
(略)
dev環境では Symfony\Component\Translation\DataCollectorTranslator がautowireされることがわかりました。
このクラスのコードを見た瞬間、メモリが消費されていく原因がわかりました(笑)
対応
services:
Symfony\Component\Translation\TranslatorInterface: '@translator.default'
もしくは、コマンドを--no-debugで実行する
一番最後で核心をついてしまいましたがsymfonyのコンテナはvar/cache以下に(envのパターン)×(debug or no-debug)の組み合わせ別にphpファイルにコンパイルされているのです。
いろいろ寄り道をした気がしますが、symfonyのサービスコンテナとautowireの内部に一歩踏み込んだとは思います。