Я получаю ошибку «из памяти» в php. Я знаю, что это может быть исправлено с помощью ini_set («memory_limit», «64M»), но я не хочу этого, потому что большая память для скрипта ненормальна. У меня есть несколько отчетов, которые настолько огромны, что мне очень нужна эта память, но обычно этого не происходит.
Проблема в том, что я даже не знаю, какой сценарий потребляет столько памяти, и ни один пользователь (пока) не сообщил об ошибке. Я знаю, что это происходит только благодаря log_errors (установленному в true) и error_log (установленному на очень заметный файл на моем рабочем столе), но он не сообщает, какой сценарий является виновником.
Любая идея о том, как это знать?
Вероятно, у вас есть некоторые основные ошибки алгоритма, создание больших структур данных, перестроение данных в виде других структур, слишком большие манипуляции с строками, загрузка целых файлов в память, повторная выборка данных из хранилища вместо повторного использования того, что было получено в последний раз, Что-то в этом роде. И многие доморощенные обработчики базы данных дают вам весь набор данных, возвращенный из вашего запроса, вместо того, чтобы предоставлять вам ресурс набора данных. Это особенно опасно для запросов, которые могут возвращать больше данных, чем первоначально предполагалось.
После того как вы профилируете свой код, вы можете начать поиск отходов памяти. Для обработки больших наборов данных регистрации структурируйте свой код для работы с одной строкой за раз, так что это (например) while( $data = mysql_fetch_assoc() )
а не foreach( $data_rows as $data )
. Это также позволяет использовать небуферизованный запрос, который также уменьшит потребление памяти.
В журнале ошибок должен указываться сценарий, который умер. Возможно, может помочь журнал ошибок Apache.
Для сценария вполне нормально использовать больше памяти, чем 32M, у меня недавно возникла проблема с использованием библиотеки GD, которая хотела бы потреблять больше, чем при масштабировании определенных типов изображений, и та же ошибка была выброшена. В вашем случае я бы удвоил память и ограничил время выполнения чем-то безопасным (если он еще не был). Я делаю это через .htaccess, с этими строками:
php_value memory_limit 64M php_value max_execution_time 30
Для этого нужен профайлер. Я предпочитаю xdebug . В этой статье объясняется, как получить информацию об использовании памяти для скрипта PHP.