Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як з'ясувати, що саме з'їдає пам'ять у PHP-скрипті?

Перший крок - виміряти. memory_get_usage() показує поточне споживання, memory_get_peak_usage() - максимум за весь час. Розставивши їх між етапами, швидко видно, де стрибок:

$before = memory_get_usage();
$rows = $repository->all();
logger()->info('rows loaded', ['mb' => (memory_get_usage() - $before) / 1024 / 1024]);

Далі - профайлер, який покаже пам'ять у розрізі функцій: Xdebug-профайлер, Blackfire, SPX, Tideways. Вони відповідають на питання «яка функція виділила ці 300 МБ».

Звичайні винуватці:

  • Завантаження всього одразу: Model::all(), file() для великого файлу, json_decode величезної відповіді. Лікується порціями: chunkById(), lazy(), генератори, потоковий парсер.
  • Накопичення в довгому процесі: статичний масив-кеш, логер, що тримає записи, DB::enableQueryLog() у воркері.
  • Циклічні посилання між об'єктами, які звільняє лише збирач сміття, а не лічильник посилань.

У довгоживучих процесах (воркери черг, Octane) навіть невеликий витік на кожному завданні з часом вбиває процес. Тому воркерам ставлять --max-jobs чи --memory, щоб вони періодично перезапускалися.

Докладніше в документації: memory_get_peak_usage

1

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання