PHP. Allowed memory size of XXXXX bytes exhausted

phpИногда мы пишем на PHP долгие скрипты, которые потребляют много-много памяти. В таких случаях мы можем столкнуться с ошибкой нехватки памяти:

Allowed memory size of XXXXX bytes exhausted

Что можно предпринять?

Память в основном забивают переменные (массивы, объекты). И если эти переменные стали не нужны — можно их освободить!

unset($BigFatVariable);

Процедура unset говорит интерпретатору, что эта переменная уже не нужна и память из под неё может быть освобождена. Однако это не всегда помогает. Дело в том, что unset не влечёт за собой автоматического освобождения памяти. Память будет освобождена лишь потом, когда сборщик мусора найдёт все неиспользуемые области памяти.

Можно запустить сборщик мусора принудительно с помощью команды

gc_collect_cycles()

Надо сказать, что сборка мусора — довольно долгая процедура и если часто её вызывать, время исполнения скрипта существенно вырастет. Просто знайте это и будьте готовы к этому.

Это кстати одна из причин, почему мусорщик не запускается автоматически при unset.

Если и это не помогло — можно исправить настройку memory_limit. Например можно увеличить лимит памяти. Можно это сделать глобально в php.ini. Но будьте осторожны, ибо память вашего сервера не резиновая и эти лимиты введены не просто так!

Гораздо более безобидно изменение лимита в конкретно вашем PHP-скрипте. Просто добавьте инструкцию:

ini_set('memory_limit', '-1');

Эта инструкция вообще снимает все ограничения памяти.

Естественно, следует соблюдать осторожность. Ибо в этом случае ваш скрипт может исчерпать память сервера и затруднить работу других процессов. Поэтому лучше запускать такие скрипты редко и лучше глубокой ночью.

PHP. Allowed memory size of XXXXX bytes exhausted: 3 комментария

  1. SunChaser

    Перед тем как кинуть Allowed memory size of XXXXX bytes exhausted как раз принудительно запускается Garbage Collector

    Так что unset должен спаспать и полагаться на него нужно, а вот gc_collect_cycles() на деле бесполезна — она существует в основном для случаев, когда автоматический garbage collector приходится отключать (например так делает composer)

  2. altesack Автор записи

    Ну не знаю, не знаю… у меня без gc_collect_cycles() память переполнялась быстрее. Чисто экспериментально установлено

  3. Nks

    Вообще не сильно хорошо писать скрипты, которые потребляют много памяти. Обычно решается сравнительно просто — в вебе скрипты ограничиваются по памяти, чистятся, а вот на сервере крутится демон (например, который обрабатывает запросы от rabbitmq) которому уже и убирается ограничение. Яркий пример — выгрузка из 1С на сайт и обработка больших данных. Иначе в один момент сервер может сказать «давай досвидания» и выдать 500, что в этой ситуации очень нехорошо.

Комментарии запрещены.