Задать вопрос

Принудитальная очистка памяти PHP?

Столкнулся с проблемой, необходимо выполнить бесконечное количество итераций. Но с каждой итерацией возрастает количество потребляемой скриптом памяти. Вот небольшой тест.



public function memory()<br>
    {<br>
        $text = 'Много текста';<br><br>
        $baseMemory = memory_get_usage();<br>
        gc_enable();<br>
        for ($x = 0; $x++ < 100000;) {<br>
            Test::create($text);<br>
            if ($x % 500 === 0) {<br>
                echo $x . "\n";<br>
                echo get_file_size(memory_get_usage() - $baseMemory), "\n";<br>
            }<br>
        }<br>
    }<br>




Память поедает Test::create($text);



Понимаю что если там в деструкторе класса вызвать функцию очистки параметров, то потребление памяти не должно возврастать, но проблема в том что класс анследует класс фреймворка, который в свою очередь вызывает еще класс, в общем сного файлов фреймворка задейстовано, которые не хотелось бы изменять.
  • Вопрос задан
  • 25407 просмотров
Подписаться 4 Оценить Комментировать
Решения вопроса 1
La2ha
@La2ha Автор вопроса
Проблема решена. Был включен профайлер запросов к базе данных. Который сохранял все запросы в переменную.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 7
@egorinsk
Если у вас есть утечка памяти в PHP. то это, как правило не баг PHP. Наверняка где-то в библиотеке, которую вы используете, есть лог или кеш и он копится, не освобпждаясь (был случай, например, когда все SQL-запросы логгировались в массив, который никогда не очищался).

Например, есть такая библиотека phpQuery, когда-то я пробовал ей пользоваться, она потребляла память в немерянных количествах.

Также утекать могут расширения вроде DOM.

В общем, изучите код внимательно и поищите сомнительные места.

Хочется послать также лучей ненависти всем, кто, не разобравшись в проблеме, пишет глупости вроде «PHP течет». В PHP система управления памятью лучше чем в других языках, так как в нем есть и Copy-on-Write, и счетчик ссылок, и сборщик мусора. Не во всех языках это доступно.
Ответ написан
Комментировать
resurtm
@resurtm
Мемлик где-то в сторонних библиотеках?
Ответ написан
return
@return
Можно попробовать периодически на каждую сотую итерацию
gc_collect_cycles()


Это — принудительный запуск Garbage Collector'а
Ответ написан
La2ha
@La2ha Автор вопроса
я создавал объект и уничножал его через unset() и NULL тоже присваивал, результат тот-же

upd: не туда
Ответ написан
Комментировать
@WEBIVAN
Писал я как-то дикое извращение, многопроцессную программу на PHP, так там каждый форк при итерации тоже безвозвратно отжирал память и количество итераций было непредсказуемым, потому условно стремилось к бесконечности.
Убил тогда день на поиск места утечки, потом забил.
Сделал что бы при съедении заданного объема памяти, програма завершалась и потом перезапускалась с того же места и так до бесконечности. Работает успешно по сей день.
Да изврашение, но в не факт что утечку вообще не удалось бы найти, ибо это PHP.
Мне вон приходится использовать в регулярка mb_ функции вместо preg_, поскольку не менее раза в неделю натыкаюсь на пары регулярка+страница в которых preg_ приводит к вылету php с segfault.
Ответ написан
KEKSOV
@KEKSOV
Приведите пожалуйста минимально-законченный кусок кода с циклом, где Вы удаляете переменную при помощи unset
Ответ написан
Praeses
@Praeses
Тоже в свое время долго игрался с потребляемой памятью в циклах, причины так и не нашел.
Как вариант решения — nohup, практически аналог форка, но новый процесс запускается независимо, ему можно передать текущий итератор цикла и в принципе любые парамеры.

В цикле можно проверять, сколько памяти использовано, и установить планку в N байт/КБ/МБ, как только память начинает приближаться к лимиту, брейкаем цикл и запускаем процесс через nohup с новыми параметрами.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы