Сталкивались ли вы с утечками памяти в PHP? Как находили и устраняли их?
Уровень: Senior
Ответ
Да, в длительно работающих скриптах или сервисах на PHP (например, демонах, воркерах) можно столкнуться с утечкой памяти, хотя PHP обычно освобождает память после окончания скрипта. Причины: накопление данных в глобальных структурах или статических переменных, бесконтрольный рост массивов, хранение ссылок на объекты, которые уже не нужны (особенно при циклических ссылках в старых версиях PHP до внедрения сборщика цикла). Для поиска утечек я использовал профилировщики/инструменты мониторинга (например, расширение Xdebug с профилировкой памяти, либо специализированные инструменты вроде memory_get_usage() в ключевых точках, или external profilers) — смотрел, как растёт память при выполнении цикла. Ещё подход: если утечка, как правило, linear — значит где-то данные накапливаются. Найдя место, устранял причину: освобождал массивы (unset()), сбрасывал большие объекты после использования, избегал хранения неограниченных логов или кэшей внутри одного процесса. В случае, если проблема в циклических ссылках, можно вызывать gc_collect_cycles() периодически, хотя в новых версиях PHP сборщик мусора должен автоматически очищать циклы. В одном из проектов помогло разделение процесса: вместо бесконечного цикла, воркер обрабатывал N задач и перезапускался — таким образом даже при небольшой утечке она не успевала стать критичной. Главное — выявить, что именно растёт, и убрать ненужные накопления или пересмотреть архитектуру хранения данных.