Как PHP скрипт может расходовать 20Гб памяти?

Добрый день!

На сервере запускаю скрипт, скрипт имеет вложенные циклы, обращается к файлам на сервере, обрабатывает их и заполняет БД.
БД некоторые таблички имеют несколько сотен тысяч записей, но выборку делаю только нужного и по индексным полям, происходит мгновенно. Тяжелых запросов нет.

Файлы хранятся с именами MD5, разбиты по папкам (.../02/a2/02a263dd93c081eefcf7f2b43e0cde43.html) в одной под папке не больше 10 файлов.

Через htop смотрю сколько он ЖРЕТ памяти, один раз застал его за поеданием 20ГБ ОЗУ, после чего его остановил и решил разобраться с ним.

через memory_get_usage() ( или memory_get_usage(true)), скрипт на старте ест 10 ... 12... мегабайт памяти, всё гуд. Но в тоже время через htop он уже отел 2-3 ГБ.

Прошу понимающих людей объяснить мне, или дать напутствие (ссылку) на понимание этого феномена.

Кто жрет ОЗУ, почему и как это исправить.

Заранее спасибо! :-)
  • Вопрос задан
  • 2551 просмотр
Решения вопроса 1
@Traney Автор вопроса
Решил проблему. Парсил файл с помощью phpQuery, там используются abstract class, экземпляр я не мог создать. Глубоко в это не погружался, но решил его заменить. Заменил на simple html dom, перестало выжирать оперативку и плюс - ощутимый прирост в скорости.
Ответ написан
Пригласить эксперта
Ответы на вопрос 6
alexey-m-ukolov
@alexey-m-ukolov Куратор тега PHP
Поставьте xhprof и всё увидите.
Ответ написан
Комментировать
alekciy
@alekciy
Вёбных дел мастер
Через htop смотрю сколько он ЖРЕТ памяти, один раз застал его за поеданием 20ГБ ОЗУ

Какой конкретно? Как минимум в htop видно 3 "вида" памяти: VIRT, RES, SHR. VIRT может быть 20ГБ. Но это не означает использование 20ГБ физической памяти.

memory_get_usage покажет текущий расход памяти. Лучше посмотреть на memory_get_peak_usage(true). И в конце скрипта.
Ответ написан
Комментировать
Комментировать
Возможно у Вас логируются запросы к БД и оперативная память возрастает.
Ответ написан
Комментировать
@newpy
web-dev
Смотря как вы файлы считываете, тем более во вложенном цикле. Построчно ли, целиком, если целиком то с помощью какого метода, посмотрите ob_get_level.
В зависимости от вашего решения, попробуйте использовать генераторы (yield) если это возможно. На мой взгляд у вас проблема кроется либо в способах чтения файлов.
Второе узкое место это запись в БД. Операции вставки всегда не дешевые, плюс если их много, попробуйте делать это транзакционно.
Ответ написан
Комментировать
@ivanovnickolay
Очищайте не использываемые переменные, особенно массивы.
Очищайте в ручную как указано тут
php.net/manual/ru/features.gc.collecting-cycles.php
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы