Я работаю с сайтом, который был построен на Drupal и в целом работает хорошо. После некоторой оптимизации требуется 20-75 МБ памяти и 0,5-2 секунды для большинства запросов. Но время от времени это занимает 15-20 секунд, и процесс будет превышать 1 ГБ + памяти.
Я пробовал отслеживать использование времени и памяти в начале и в конце выполнения PHP (помещая код в index.php Drupal), и он не показывает ничего необычного (он сообщает о разнице в 1 секунду между началом и концом, а также памятью использование увеличивается до 72 МБ в одном примере). Каким-то образом PHP использует много ресурсов, но не в реальном коде PHP.
Впервые это наблюдалось с помощью apache. Переход на новый сервер (с использованием стандартных пакетов Ubuntu) сделал сайт немного более надежным, но это все равно происходит. Даже после переключения на nginx + php-fpm и полного отключения apache процессы php-fpm показывают тот же образец использования памяти. Помимо стандартных модулей PHP, единственными дополнениями являются memcache, stats и xhprof.
Что может показать, почему PHP использует так много памяти вне самого скрипта?
Я считаю, что утечки памяти довольно распространены в php и его библиотеках. Также обычно кэш кода операции PHP использует большую часть памяти, предоставленной PHP.
Вы на 100% уверены, что у вас есть файлы дампа xhprof для проблемной ситуации, и они не показывают чрезмерного использования памяти?
Если вы правы - вам нужно создавать и анализировать дампы ядра подозрительных процессов PHP с помощью gdb - для этого требуются некоторые базовые знания C.
Также проверьте трекеры ошибок для вашей версии php и libs.
Скорее всего, у вас в Drupal включен неэффективный модуль. Для начала отключите все это и посмотрите, изменится ли это что-нибудь.
Кроме того, похоже, что ваш след не настоящий трассировка, взгляните на это, чтобы получить лучшую трассировку: http://www.youtube.com/watch?v=eF-p--AH37E
Кэш кода операции (APC) поможет вам только во имя производительности, поэтому я бы посмотрел туда в последнюю очередь, чтобы повысить производительность.
Оказалось, что функция использует register_shutdown для запуска после окончания основного кода (для отображения отладочной информации). Это объясняет, почему он не отображается в журнале, который я сделал, или в xhprof, который завершился перед функцией выключения. Изменение этого, похоже, решило проблему на данный момент.