Все самое полезное для пхпшника в одном канале.
По рекламе: @tproger_sales_bot
Учиться у нас: clc.to/M561SQ
Для обратной связи: @proglibrary_feeedback_bot
РКН: https://gosuslugi.ru/snet/67a5d13cd6fa92100ee6f68b
Post #6676
2.08K
📈 Почему память в PHP-воркерах только растёт — и это нормально
Если вы переходите с PHP-FPM на RoadRunner, Laravel Queue или Symfony Messenger — вы увидите один и тот же эффект:
Память растёт ступеньками и никогда не падает.
Это не утечка. Это архитектура PHP.
🔵 Почему так происходит
PHP использует Zend Memory Manager: он выделяет память крупными чанками (2–4 МБ) и не отдаёт их ОС назад, даже если внутри всё освобождено.
Каждый пик — новый baseline. Обработали 100k записей → память выросла → процесс будет держать этот объём до конца жизни.
🔥 Что вызывает «разбухание»
✅ Как проектировать правильно
— Стриминг вместо коллекций:
или:
— Изоляция тяжёлых операций в функцию — память освобождается при выходе из scope.
— Ротация воркеров — обязательна:
Библиотека пхпшника
Если вы переходите с PHP-FPM на RoadRunner, Laravel Queue или Symfony Messenger — вы увидите один и тот же эффект:
Память растёт ступеньками и никогда не падает.
40 → 200 → 350 МБ… и так до перезапуска.
Unset, GC, collect_cycles() — не помогают.
Это не утечка. Это архитектура PHP.
🔵 Почему так происходит
PHP использует Zend Memory Manager: он выделяет память крупными чанками (2–4 МБ) и не отдаёт их ОС назад, даже если внутри всё освобождено.
Каждый пик — новый baseline. Обработали 100k записей → память выросла → процесс будет держать этот объём до конца жизни.
🔥 Что вызывает «разбухание»
ORM ->all() или ->get() на десятки тысяч записей
большой файл в file_get_contents()
накопление массивов
сложные eager-loading графы ORM
✅ Как проектировать правильно
— Стриминг вместо коллекций:
User::lazy()->each(fn($u) => processUser($u));
или:
Record::chunk(100, function ($rows) {
foreach ($rows as $r) processRecord($r);
});
✔️ Doctrine:
foreach ($q->toIterable() as $u) {
process($u);
$em->detach($u);
}
— Изоляция тяжёлых операций в функцию — память освобождается при выходе из scope.
— Ротация воркеров — обязательна:
Laravel:
php artisan queue:work --max-jobs=1000
RoadRunner:
pool:
max_jobs: 1000
Messenger:
messenger:consume --limit=1000
Библиотека пхпшника
- 🔥 8
- 😁 3
- 🤔 3
- 👍 2
- ❤ 1








