O que está causando "Não é possível alocar memória para o pool" no PHP?

133

Ocasionalmente, eu me deparo com o limite de alocação de memória de um servidor, principalmente com um aplicativo inchado como o Wordpress, mas nunca encontrei "Não é possível alocar memória para o pool" e com problemas para rastrear qualquer informação.

Alguém sabe o que isso significa? Eu tentei aumentar o memory_limitsem sucesso. Também não fiz alterações significativas no aplicativo. Um dia não houve problema, no dia seguinte eu acertei esse erro.

jonathanatx
fonte

Respostas:

90

Provavelmente está relacionado à APC.

Para as pessoas com esse problema, especifique as configurações de .ini. Especificamente sua configuração apc.mmap_file_mask.

Para mmap suportado por arquivo, ele deve ser definido como algo como:

apc.mmap_file_mask=/tmp/apc.XXXXXX

Para mapear diretamente de / dev / zero, use:

apc.mmap_file_mask=/dev/zero

Para mmap suportado por memória compartilhada compatível com POSIX, use:

apc.mmap_file_mask=/apc.shm.XXXXXX
Frankie
fonte
Obrigado! Esse é exatamente o link que eu estava procurando. Agradecemos a ajuda!
jonathanatx
2
Descobri que essas mudanças não corrigir o problema, como os comentários sobre o fio ligado também o documento ...
Jonathan dia
3
Mais informações para essa configuração APC: php.net/apc.configuration#ini.apc.mmap-file-mask
mikeytown2
2
No meu caso, tive que mudar de backup de arquivo para compatível com POSIX para livrar-me do erro.
Attila Fulop
4
Não consigo entender como essa resposta resolve o problema. O erro ocorre quando esse file_masknão é um desses valores? Se eu tiver um desses valores e estiver recebendo o erro, preciso alterá-lo para outro? Qual?
Jeff
125

Usar um TTL de 0 significa que a APC liberará todo o cache quando a memória ficar sem memória. O erro não aparece mais, mas torna a APC muito menos eficiente. É uma decisão sem risco, sem problemas, "não quero fazer meu trabalho". A APC não deve ser usada dessa maneira. Você deve escolher um TTL alto o suficiente para que as páginas mais acessadas não expirem. O melhor é fornecer memória suficiente para que a APC não precise liberar o cache.

Basta ler o manual para entender como o ttl é usado: http://www.php.net/manual/en/apc.configuration.php#ini.apc.ttl

A solução é aumentar a memória alocada para a APC. Faça isso aumentando apc.shm_size.

Se a APC for compilada para usar a Memória de segmento compartilhada, você será limitado pelo seu sistema operacional. Digite este comando para ver o limite do seu sistema para cada segmento:

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

Para alocar mais memória, você precisará aumentar o número de segmentos com o parâmetro apc.shm_segments.

Se a APC estiver usando memória mmap, você não terá limite. A quantidade de memória ainda é definida pela mesma opção apc.shm_size.

Se não houver memória suficiente no servidor, use a opção de filtros para impedir que arquivos php acessados ​​com menos frequência sejam armazenados em cache.

Mas nunca use um TTL de 0.

Como o c33s disse, use o apc.php para verificar sua configuração. Copie o arquivo do pacote apc para uma pasta da Web e aponte o navegador para ele. Você verá o que realmente está alocado e como é usado. Os gráficos devem permanecer estáveis ​​após o horário de funcionamento, se forem completamente alterados a cada atualização, significa que sua configuração está incorreta (a APC está liberando tudo). Aloque 20% a mais de RAM do que a APC realmente usa como margem de segurança e verifique-a regularmente.

O padrão de permitir apenas 32 MB é ridiculamente baixo. O PHP foi projetado quando os servidores tinham 64 MB e a maioria dos scripts usava um arquivo php por página. Atualmente, soluções como o Magento exigem mais de 10k arquivos (~ 60Mb na APC). Você deve permitir memória suficiente para que a maioria dos arquivos php seja sempre armazenada em cache. Não é um desperdício, é mais eficiente manter o opcode no ram do que ter o php bruto correspondente no cache de arquivos. Atualmente, podemos encontrar servidores dedicados com 24 GB de memória por apenas US $ 80 / mês, portanto, não hesite em permitir vários GB à APC. Coloquei 2 GB de 24 GB em um servidor que hospeda as lojas 5Magento e o site ~ 40 wordpress, a APC usa 1,2 GB. Conte 64 MB para a instalação do Magento, 40 MB para um Wordpress com alguns plugins.

Além disso, se você tiver sites de desenvolvimento no mesmo servidor. Exclua-os do cache.

bokan
fonte
2
Este! Estou executando o Wordpress e 32M simplesmente não era suficiente. Aumentou para 64 milhões e agora está livre. Verifique as pessoas apc.php!
Dave Drager
Boa resposta! +1 Obrigado.
Kostanos
Para aumentar para 64M, você precisa adicionar apc.shm_size = 64 e não apc.shm_size = 64M (a maioria dos exemplos que eu já tinha um M no final) Não funcionou na minha versão do apc (v3.1.3p1)
Patrick Esqueça
1
Você está assumindo que terá muitos arquivos em cache que estão no cache há mais tempo que o TTL. c33s tem um ponto importante. Se tudo foi acessado recentemente (digamos que você tenha 70% do cache acessado o tempo todo como quiser e tenha um grande pico em que muitos arquivos infrequentes extras serão adicionados de uma só vez), você receberá erros jogado por segundos TTL. O cache está cheio, e você disse à APC que não deve limpar essas entradas para reclamar. Se você tiver TTL por 5 horas, terá 5 horas de erros aguardando a expiração desses arquivos não frequentes.
Matthew Kolb
@ MatthewKolb: Você não deve permitir o armazenamento em cache de mais arquivos do que a APC pode conter em sua memória. Use filtros para impedir que arquivos acessados ​​com frequência não sejam armazenados em cache.
bokan
36

solução para mim:

  • apc.ttl = 0
  • apc.shm_size = o que você quiser

editar início

Aviso!

@bokan me indicou que eu deveria adicionar um aviso aqui.

se você tiver um ttl de 0, isso significa que todos os itens em cache podem ser eliminados imediatamente. portanto, se você tiver um tamanho de cache pequeno como 2mb e um ttl de 0, isso tornará o apc inútil, porque os dados no cache são sempre substituídos.

abaixar o ttl significa apenas que o cache não pode ficar cheio, apenas com itens que não podem ser substituídos.

então você precisa escolher um bom equilíbrio entre ttl e tamanho do cache.

no meu caso, eu tinha um tamanho de cache de 1gb, por isso era mais do que suficiente para mim.

editar final

teve o mesmo problema no centos 5 com php 5.2.17 e percebeu que se o tamanho do cache for pequeno e o parâmetro ttl for "alto" (como 7200) enquanto tiver muitos arquivos php para armazenar em cache, o cache será preenchido rapidamente e o apc não encontra nada que possa ser removido porque todos os arquivos no cache ainda cabem no ttl.

aumentar o tamanho da memória é apenas uma solução parcial, você ainda executará esse erro se o cache for preenchido e todos os arquivos estiverem dentro do ttl.

então minha solução foi definir o ttl como 0, então o apc preenche o cache e sempre existe a possibilidade do apc limpar alguma memória para novos dados.

espero que ajude

edit: veja também: http://pecl.php.net/bugs/bug.php?id=16966

faça o download de http://pecl.php.net/get/APC extrair e execute o apc.php, você tem um bom diagrama de como é o uso do cache

c33s
fonte
2
Obrigado, isso ajudou. Eu estava recebendo cerca de uma dúzia de erros "Não foi possível alocar memória" por segundo. Dobrei o tamanho do meu cache (32 a 64 MB) e reduzi o ttl para 0. Isso removeu completamente esses erros.
Nicktacular 23/05
1
Essa foi a correção em nossos servidores.
23711 Justin
1
Isso pareceu resolver o problema para mim também.
anisoptera
1
Usando o ZWAMP e isso parece ter funcionado também. Obrigado.
WernerCD
10
Esta não é uma solução! O erro desaparece, mas a APC estará quase desativada. Ele limpará todo o cache sempre que a memória estiver cheia. Basta ler o manual que Brideau nos deu. php.net/manual/en/apc.configuration.php#ini.apc.ttl.
Bokan
7

A execução do script apc.php é essencial para entender qual é o seu problema, IMO. Isso nos ajudou a dimensionar nosso cache corretamente e, no momento, parece ter resolvido o problema.

Brice D
fonte
1
como c33s disse: Download pecl.php.net/get/APC extrair e executar o apc.php, lá você tem um diagrama agradável como o cache uso olhar como
Bokan
4

Para iniciantes como eu, esses recursos ajudaram:

Localizando o arquivo apc.ini para fazer as alterações recomendadas pelos c33s acima e definindo os valores recomendados: http://www.untwistedvortex.com/optimizing-tuning-apc-alternate-php-cache/

Compreendendo o que é apc.ttl: http://www.php.net/manual/en/apc.configuration.php#ini.apc.ttl

Compreendendo o que é apc.shm_size: http://www.php.net/manual/en/apc.configuration.php#ini.apc.shm-size

Brideau
fonte
Obrigado, você apontou a solução certa. Reduzir o TTL é como desativar a APC.
Bokan
4

Como Bokan mencionou, você pode aumentar a memória, se disponível, e ele está certo quanto à definição contraproducente de TTL para 0.

Nota: Foi assim que corrigi este erro para o meu problema específico. É um problema genérico que pode ser causado por várias coisas; portanto, siga apenas o abaixo se você receber o erro e achar que isso foi causado pelo carregamento de arquivos PHP duplicados no APC.

O problema que eu estava tendo era quando lancei uma nova versão do meu aplicativo PHP. Ou seja, substituiu todos os meus arquivos .php por novos. A APC carregaria ambas as versões no cache.

Como eu não tinha memória suficiente para duas versões dos arquivos php, a APC fica sem memória.

Existe uma opção chamada apc.stat para informar à APC para verificar se um arquivo específico foi alterado e, se for o caso, substituí-lo. Isso normalmente é bom para o desenvolvimento, porque você está constantemente fazendo alterações, no entanto, na produção, geralmente é desativado como no meu case - http://www.php.net/manual/en/apc.configuration.php#ini.apc.stat

Ativar o apc.stat resolveria esse problema se você concordasse com o desempenho.

A solução que eu encontrei para o meu problema é verificar se a versão do projeto foi alterada e, se houver, esvaziar o cache e recarregar a página.

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);
}
Jase Whatson
fonte
2

Isso funcionou para os nossos funcionários (executando vários sites do Wordpress no mesmo servidor).

Alteradas as configurações de memória no arquivo /etc/php.d/apc.ini. Como foi definido para 64M, dobramos para 128M.

apc.shm_size = 128M

Peter Drinnan
fonte
1

Olhando para as internets, pode haver várias causas. No meu caso, deixando tudo padrão, exceto ...

apc.shm_size = 64M

... cancelou os incontáveis ​​avisos que eu estava recebendo antes.

Leo
fonte
1

Recebi o erro "Não é possível alocar memória para o pool" depois de mover uma instalação do OpenCart para um servidor diferente. Eu também tentei aumentar o memory_limit.

O erro parou depois que alterei as permissões do arquivo na mensagem de erro para ter acesso de gravação pelo usuário que o apache executa como (apache, www-data, etc.). Em vez de modificar o arquivo / etc / group diretamente (ou alterar os arquivos para 0777), usei o usermod:

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

Então eu tive que reiniciar o apache para que a alteração tivesse efeito:

apachectl restart

Ou

sudo /etc/init.d/httpd restart

Ou o que seu sistema usa para reiniciar o apache.

Se o site estiver em hospedagem compartilhada, talvez você precise alterar as permissões de arquivo com um programa FTP ou entre em contato com o provedor de hospedagem?

Brent Self
fonte
1

Para resolver esse problema, defina o valor para apc.shm_size como número inteiro Localize o arquivo apc.ini (no meu sistema, local do arquivo apc.ini /etc/php5/conf.d/apc.ini) e defina: apc.shm_size = 1000

Bialy7
fonte
1

no meu sistema, tive que inserir apc.shm_size = 64M no /usr/local/etc/php.ini (FreeBSD 9.1) e depois quando olhei para o apc.php (que copiei de / usr / local / share / doc / APC /apc.php para / usr / local / www / apache24 / data) descobri que o tamanho do cache havia aumentado do padrão de 32M para 64M e não estava mais recebendo uma contagem total de cache grande

referências: http://au1.php.net/manual/en/apc.configuration.php também leram os comentários de Bokan, foram muito úteis

andrew
fonte
0

Monitore o tamanho dos arquivos em cache (você pode usar o apc.php do pacote apc pecl) e aumente o apc.shm_size de acordo com suas necessidades.

Isso resolve o problema.

lazcorp
fonte