Что вызывает «Невозможно выделить память для пула» в PHP?

133

Я иногда сталкивался с ограничением выделения памяти на сервере, особенно с раздутым приложением, таким как Wordpress, но никогда не сталкивался с «Невозможно выделить память для пула» и иметь проблемы с отслеживанием любой информации.

Кто-нибудь знает что это значит? Я пытался увеличить memory_limitбезуспешно. Я также не внес существенных изменений в приложение. Однажды проблем не было, на следующий день я столкнулся с этой ошибкой.

jonathanatx
источник

Ответы:

90

Наверное, это связано с APC.

Для тех, кто сталкивается с этой проблемой, укажите настройки .ini. В частности, ваш параметр apc.mmap_file_mask.

Для mmap с файловой поддержкой должно быть установлено что-то вроде:

apc.mmap_file_mask=/tmp/apc.XXXXXX

Для mmap прямо из / dev / zero используйте:

apc.mmap_file_mask=/dev/zero

Для POSIX-совместимого mmap с поддержкой разделяемой памяти используйте:

apc.mmap_file_mask=/apc.shm.XXXXXX
Фрэнки
источник
Спасибо! Это именно та ссылка, которую я искал. Ценю помощь!
jonathanatx
2
Я обнаружил, что эти изменения не решают проблему, поскольку комментарии к связанной цепочке также документируют ...
Джонатан Дэй,
3
Дополнительная информация об этой настройке APC: php.net/apc.configuration#ini.apc.mmap-file-mask
mikeytown2 05
2
В моем случае мне пришлось перейти с файловой поддержки на POSIX-совместимую, чтобы избавиться от ошибки.
Аттила Фулоп,
4
Я не понимаю, как этот ответ решает проблему. Ошибка возникает, когда file_maskне одно из этих значений? Если у меня есть одно из этих значений, и я получаю сообщение об ошибке, нужно ли мне переключить его на другое? Который из?
Джефф
125

Использование TTL равного 0 означает, что APC очистит весь кеш, когда ему не хватит памяти. Ошибка больше не появляется, но это снижает эффективность APC. Это не риск, не проблема: «Я не хочу делать свою работу». APC не предназначен для использования таким образом. Вы должны выбрать достаточно высокий TTL, чтобы срок действия наиболее часто используемых страниц не истек. Лучше всего выделить достаточно памяти, чтобы APC не нужно было очищать кеш.

Просто прочтите руководство, чтобы понять, как используется ttl: http://www.php.net/manual/en/apc.configuration.php#ini.apc.ttl

Решение - увеличить объем памяти, выделенной APC. Сделайте это, увеличив apc.shm_size.

Если APC скомпилирован для использования общей сегментной памяти, вы будете ограничены вашей операционной системой. Введите эту команду, чтобы увидеть предел вашей системы для каждого сегмента:

sysctl -a | grep -E "shmall|shmmax"

Чтобы выделить больше памяти, вам нужно увеличить количество сегментов с помощью параметра apc.shm_segments.

Если APC использует память mmap, у вас нет ограничений. Объем памяти по-прежнему определяется той же опцией apc.shm_size.

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

Но никогда не используйте значение TTL равное 0.

Как сказал c33s, используйте apc.php для проверки вашей конфигурации. Скопируйте файл из пакета apc в веб-папку и укажите его в браузере. Вы увидите, что на самом деле выделено и как оно используется. Графики должны оставаться стабильными в нерабочее время, если они полностью меняются при каждом обновлении, это означает, что ваша настройка неверна (APC все стирает). Выделите на 20% больше оперативной памяти, чем действительно используется APC в качестве запаса прочности, и регулярно проверяйте ее.

По умолчанию разрешено только 32 МБ - это смехотворно мало. PHP был разработан, когда серверы имели размер 64 МБ, и большинство скриптов использовали один файл php на страницу. В настоящее время для таких решений, как Magento, требуется более 10k файлов (~ 60 МБ в APC). Вы должны выделить достаточно памяти, чтобы большинство файлов php всегда кэшировалось. Это не пустая трата времени, гораздо эффективнее хранить код операции в оперативной памяти, чем иметь соответствующий необработанный php в файловом кеше. В настоящее время мы можем найти выделенные серверы с 24 ГБ памяти всего за 80 долларов в месяц, так что не стесняйтесь предоставить APC несколько ГБ. Я поставил 2 ГБ из 24 ГБ на сервер, на котором размещены магазины 5Magento и ~ 40 веб-сайтов WordPress, APC использует 1,2 ГБ. Считайте 64 МБ для установки Magento, 40 МБ для Wordpress с некоторыми плагинами.

Также, если у вас есть веб-сайты для разработки на одном сервере. Исключить их из кеша.

Bokan
источник
2
Это! Я использую Wordpress, и 32M было недостаточно. Увеличен до 64M и теперь в чистом виде. Проверяйте apc.php у людей!
Дэйв Драгер
Хороший ответ! +1 Спасибо.
Костанос
Чтобы увеличить до 64M, вам нужно добавить apc.shm_size = 64, а не apc.shm_size = 64M (в большинстве примеров, которые я видел, в конце была буква M). Не работал с моей версией apc (v3.1.3p1)
Patrick Forget
1
Вы предполагаете, что у вас будет много кэшированных файлов, которые находятся в кеше дольше, чем TTL. c33s имеет важное замечание. Если ко всему недавно обращались (скажем, у вас есть 70% кеша, доступ к которому осуществляется постоянно, как вы хотите, и есть большой всплеск, когда сразу добавляется много дополнительных нечастых файлов), вы получите ошибки брошен в течение TTL секунд. Кэш заполнен, и вы сказали APC, что он не должен очищать эти записи, поэтому он жалуется. Если у вас TTL в течение 5 часов, вы получите 5 часов ошибок, ожидающих истечения срока действия этих нечастых файлов.
Мэтью Колб
@MatthewKolb: вы не должны разрешать кэширование большего количества файлов, чем APC может хранить в своей памяти. Используйте фильтры, чтобы предотвратить кэширование файлов, к которым редко обращаются.
bokan
36

решение для меня:

  • apc.ttl = 0
  • apc.shm_size = все, что вы хотите

редактировать начало

предупреждение!

@bokan указал мне, что я должен добавить предупреждение здесь.

если у вас ttl 0, это означает, что каждый кешированный элемент может быть немедленно очищен. поэтому, если у вас небольшой размер кеша, например 2 МБ, и ttl, равный 0, это сделает apc бесполезным, потому что данные в кеше всегда перезаписываются.

понижение ttl означает только то, что кеш не может быть заполнен, только элементами, которые нельзя заменить.

поэтому вам нужно выбрать хороший баланс между ttl и размером кеша.

в моем случае у меня был размер кеша 1 ГБ, так что мне этого было более чем достаточно.

редактировать конец

имел ту же проблему на centos 5 с php 5.2.17 и заметил, что если размер кеша мал, а параметр ttl - «высокий» (например, 7200) при наличии большого количества файлов php для кеширования, то кеш заполняется довольно быстро и apc не находит ничего, что можно было бы удалить, потому что все файлы в кеше по-прежнему помещаются в ttl.

Увеличение размера памяти - это лишь частичное решение, вы все равно столкнетесь с этой ошибкой, если вы заполните кеш и все файлы находятся в пределах ttl.

поэтому я решил установить для ttl значение 0, поэтому apc заполняет кеш, и всегда есть возможность для apc очистить некоторую память для новых данных.

надеюсь, это поможет

изменить: см. также: http://pecl.php.net/bugs/bug.php?id=16966

загрузите http://pecl.php.net/get/APC extract и запустите apc.php, там у вас есть хорошая диаграмма, как выглядит использование вашего кеша

c33s
источник
2
Спасибо, это помогло. Я получал около дюжины ошибок «Невозможно выделить память» в секунду. Я удвоил размер кэша (с 32 до 64 МБ) и снизил ttl до 0. Это полностью устранило эти ошибки.
nicktacular
1
Это было исправлением на наших серверах.
Джастин
1
Похоже, это решило и мою проблему.
анизоптера
1
Использование ZWAMP, и это, похоже, тоже помогло. Спасибо.
WernerCD
10
Это не выход! Ошибка исчезнет, ​​но APC будет почти отключен. Он будет очищать весь кеш каждый раз при заполнении памяти. Просто прочтите руководство, которое дал нам Бридо. php.net/manual/en/apc.configuration.php#ini.apc.ttl.
bokan
7

Запуск сценария apc.php является ключом к пониманию вашей проблемы, ИМО. Это помогло нам правильно определить размер кеша и, похоже, на данный момент решило проблему.

Брайс Д
источник
1
как сказал c33s: загрузите pecl.php.net/get/APC extract и запустите apc.php, там у вас есть хорошая диаграмма, как выглядит использование вашего кеша
bokan
4

Новичкам вроде меня помогли эти ресурсы:

Поиск файла apc.ini для внесения изменений, рекомендованных c33s выше, и установка рекомендуемых сумм: http://www.untwistedvortex.com/optimizing-tuning-apc-alternate-php-cache/

Понимание того, что такое apc.ttl: http://www.php.net/manual/en/apc.configuration.php#ini.apc.ttl

Что такое apc.shm_size: http://www.php.net/manual/en/apc.configuration.php#ini.apc.shm-size

Brideau
источник
Спасибо, вы указали правильное решение. Понижение TTL похоже на отключение APC.
bokan
4

Как упоминал Бокан, вы можете увеличить объем памяти, если он доступен, и он прав в том, насколько непродуктивно установка TTL на 0.

Примечание: вот как я исправил эту ошибку для моей конкретной проблемы. Это общая проблема, которая может быть вызвана распределением вещей, поэтому следуйте приведенным ниже инструкциям, только если вы получили ошибку и считаете, что это вызвано дублированием файлов PHP, загружаемых в APC.

У меня возникла проблема, когда я выпустил новую версию своего PHP-приложения. Т.е. заменил все мои .php файлы на новые, APC загрузит обе версии в кеш.

Поскольку у меня не хватило памяти для двух версий файлов php, APC не хватило бы памяти.

Существует опция apc.stat, которая сообщает APC, что нужно проверить, изменился ли конкретный файл, и, если да, заменить его, это обычно нормально для разработки, потому что вы постоянно вносите изменения, однако на производстве он обычно отключается, как это было в моем примере. случай - http://www.php.net/manual/en/apc.configuration.php#ini.apc.stat

Включение apc.stat решит эту проблему, если вас устраивает снижение производительности.

Решение, которое я придумал для моей проблемы, - это проверить, изменилась ли версия проекта, и если да, очистить кеш и перезагрузить страницу.

define('PROJECT_VERSION', '0.28'); 

if(apc_exists('MY_APP_VERSION') ){

    if(apc_fetch('MY_APP_VERSION') != PROJECT_VERSION){
        apc_clear_cache();
        apc_store ('MY_APP_VERSION', PROJECT_VERSION);
        header('Location: ' . 'http'.(empty($_SERVER['HTTPS'])?'':'s').'://'.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI']);
        exit;  
    }

}else{
    apc_store ('MY_APP_VERSION', PROJECT_VERSION);
}
Джейс Уотсон
источник
2

Это сработало для наших ребят (запустив множество сайтов Wordpress на одном сервере).

Изменены настройки памяти в файле /etc/php.d/apc.ini. Он был установлен на 64M, поэтому мы удвоили его до 128M.

apc.shm_size = 128M

Питер Дриннан
источник
1

Если посмотреть на интернет, то причины могут быть разными. В моем случае оставлю все по умолчанию, кроме ...

apc.shm_size = 64M

... убрал бесчисленные предупреждения, которые я получал ранее.

Лео
источник
1

Я получил сообщение об ошибке «Невозможно выделить память для пула» после переноса установки OpenCart на другой сервер. Еще пробовал поднять memory_limit.

Ошибка прекратилась после того, как я изменил права доступа к файлу в сообщении об ошибке, чтобы получить доступ на запись для пользователя, от имени которого работает apache (apache, www-data и т. Д.). Вместо того, чтобы напрямую изменять / etc / group (или изменять файлы с помощью chmod до 0777), я использовал usermod:

usermod -a -G vhost-user-group apache-user

Затем мне пришлось перезапустить apache, чтобы изменения вступили в силу:

apachectl restart

Или

sudo /etc/init.d/httpd restart

Или то, что ваша система использует для перезапуска apache.

Если сайт находится на виртуальном хостинге, возможно, вам нужно изменить права доступа к файлам с помощью программы FTP или связаться с провайдером хостинга?

Брент Селф
источник
1

Чтобы решить эту проблему, установите значение apc.shm_size как целое число. Найдите свой файл apc.ini (в моей системе расположение файла apc.ini /etc/php5/conf.d/apc.ini) и установите: apc.shm_size = 1000

Bialy7
источник
1

в моей системе мне пришлось вставить apc.shm_size = 64M в /usr/local/etc/php.ini (FreeBSD 9.1), а затем, когда я посмотрел на apc.php (который я скопировал из / usr / local / share / doc / APC /apc.php to / usr / local / www / apache24 / data) я обнаружил, что размер кеша увеличился с 32 МБ по умолчанию до 64 МБ, и я больше не получал большое количество полных кешей

ссылки: http://au1.php.net/manual/en/apc.configuration.php также прочтите комментарии Бокана, они были очень полезны

Андрей
источник
0

Следите за размером кэшированных файлов (вы можете использовать apc.php из пакета apc pecl) и увеличивайте apc.shm_size в соответствии с вашими потребностями.

Это решает проблему.

lazcorp
источник