У меня есть PHP-скрипт, который работает бесконечно длинный (бесконечный цикл основного события), обрабатывая поток входящих твитов из Twitter и сохраняя их в MySQL. Тем не менее, я не могу заставить его использовать память под контролем. Я нашел 3 способа измерения использования памяти:
memory_get_usage()
– Отчеты о 4.0 MB memory_get_usage(true)
– сообщает о 7,5 МБ exec("ps -o rss -p " . getmypid(), $memOutput);
– Сообщает о линейно растущем числе, которое быстро растет до сотен МБ за 60 минут или меньше и продолжает расти до тех пор, пока скрипт не будет принудительно завершен. Мои вопросы:
1) Какова практическая разница между этими тремя мерами?
Но главным образом:
2) Что это означает, если первые два являются относительно постоянными, но третий метод одичал из-под контроля, как это?
FWIW, я использую PHP 5.3 с Zend Framework 1.x и много активности Zend_Db. Скрипт запускается под CLI SAPI. Zend_Db_Profiler не используется. У меня также есть второй бесконечно запущенный скрипт, который вообще не использует базу данных, а использование памяти является постоянным. Поэтому, похоже, это связано с базой данных, возможно, с расширением MySQL, которое использует моя PHP-установка, или, может быть, с Zend_Db. Я сделал большие усилия в своем коде, чтобы избежать кэширования объектов небрежно, хотя я не сделал этого с самим кодом Zend.
Я попытался сделать свой сценарий вызовом gc_enable()
и периодически запускать gc_collect_cycles()
, но это не помогает.
Есть идеи?
Редактировать Я намерен профилировать этот код, как только смогу, но тем временем я заметил, что даже мои скрипты, которые не касаются БД, также утечки памяти. Но они делают это гораздо медленнее, что становится очевидным только при сравнении использования памяти в течение нескольких дней.
Ну, я не могу указать вам на точный ответ здесь, потому что вам нужно сделать профилирование самостоятельно. Из того, что вы говорите, кажется, что он указывает на уровень базы данных Zend, однако вы не можете быть уверены, если не выполните его. 😉
В UNIX / Linux (и я надеюсь, что вы правильно используете PHP – путь UNIX / Linux: D) есть некоторые очень полезные инструменты для профилирования таких приложений на системном уровне и проверки использования экземпляров и памяти в приложении PHP. Вы можете использовать Valgrind для получения информации, например:
valgrind --tool=callgrind --dump-instr=yes -v --instr-atstart=no /usr/sbin/apache2 -X
Обратите внимание, что Valgrind – это набор инструментов, и здесь мы используем инструмент «callgrind» – он
предоставляет всю информацию, которую делает Cachegrind, а также дополнительную информацию о callgraphs
Это создаст файл callgrind.out
или их набор, который я не могу запомнить. В любом случае теперь вы можете использовать Kcachegrind для визуализации собранной информации:
kcachegrind callgrind.out
вы не увидите визуализацию вызовов и процент памяти, которую использует определенная часть вашего приложения. Что-то вроде:
Вы также можете попробовать некоторые другие инструменты в наборе Valgrind, например Memcheck, чтобы увидеть
все чтения и записи памяти и звонки в malloc / new / free / delete
Сначала я узнал о Valgrind при попытке профилировать свой Linux-сервер. Затем я немного изучил, и оказалось, что это очень хороший инструмент для профилирования PHP-приложений … Здесь очень хорошо говорят . Я использовал некоторые из примеров. Проверьте это!
И после того, как вы профилируете свое приложение, вернитесь с информацией о том, что это было, или что вы видите и т. Д. Мне будет очень интересно проанализировать это. Надеюсь, это помогло. 😉
EDIT: Теперь я вспоминаю, что я пропустил некоторые вещи. : D Вы также можете попробовать использовать APD, который является расширением zend, а также может предоставить полезную информацию . Я лично его не использовал, но есть несколько хороших примеров в Интернете.
Другой вариант – Xhprof – Иерархический Профайлер. Вы можете использовать это для сбора разных показателей . В конце следует использовать комбинацию этих инструментов. Как и почему зависит от вас.