Использование памяти в PHP

Fatal error: Allowed memory size of XXXX bytes exhausted (tried to allocate YY bytes) Думаю каждый разработчик на php хоть раз видел подобную надпись.

Вроде бы ваш скрипт вполняет довольно простую и рутинную задачу, а памяти ему уже не хватает. Это происходит довольно часто, когда вы работаете с большим объемом данных, базами данных MySQL или пишите парсер контента. Рассмотрим варианты решения этой проблемы.

Первое и самое простое что вы можете сделать, это увеличить количество памяти выделяемое сервером для нужд php. Сделать это можно следующим образом: Если у вас свой сервер и вы имеет доступ к php.ini, то можете увеличить значение переменной memory_limit: memory_limit = 32M; Это увеличит максимальное количество памяти выделяемое php скрипту. Если доступа к php.ini нет, то можно попробовать изменить значение memory_limit другим способом, добавьте следующие строки в ваш php файл.

Но к сожалению не на всех серверах это разрешено. Хотя может это и к лучшему, иначе никто бы не занимался оптимизацией своих приложений. Если описаный выше способ не сработал, можете попробовать указать значение через файл .htaccess:

Ну и если ничего из этого не помогло, то переходим к тому ради чего была написана эта статья, к оптимизации кода. Вашим главным оружием в войне за память в php будет функции unset() и прямые руки. Garbage collector(сборщик мусоры) появился только в php версии 5.3 и работает он довольно загадочно, поэтому хороший код все еще в моде. Утечка памяти при использовании preg_match

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

Тут дело в том, что php язык с динамической типизацией и хотя вы можете указать что переменная будет строковой, мы не можем указать сколько памяти ей потребуется. Поэтому php выделят под веременную определеное количество памяти, и когда этого пространства в памяти не хватет (мы увеличиваем длинну строки), создается копия этой переменной в памяти и под нее выделятся еще памяти, при этом старые даные никуда не денуться (возможно в php 5.3 эту проблему решает garbage collector), таким образом память утекает с невероятной скоростью. Решить проблему можно использованием массивов.

Тут проблема в строчке $var = getData(). Когда первый раз переменой $var присваивается значение, она очень мала и ее копия в памяти незначительна, но уже при второй итерации переменая $var существует и создается ее копия в памяти, которая уже существенна. Решить проблему поможет функция unset().

Это предотвратит дублирование в памяти переменной $var.

Комментарии Disqus