Eu tenho vários sistemas de ponto de venda (POS) do cliente que enviam periodicamente novos dados de vendas para um banco de dados centralizado, que armazena os dados em um grande banco de dados para geração de relatórios.
O POS do cliente é baseado no PHPPOS, e eu implementei um módulo que usa a biblioteca XML-RPC padrão para enviar dados de vendas ao serviço. O sistema do servidor é construído no CodeIgniter e usa as bibliotecas XML-RPC e XML-RPCS para o componente de serviço da web. Sempre que envio muitos dados de vendas (apenas 50 linhas da tabela de vendas e linhas individuais de sales_items pertencentes a cada item da venda), recebo o seguinte erro:
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 54 bytes)
128M é o valor padrão php.ini
, mas presumo que seja um número enorme para quebrar. Na verdade, eu até tentei definir esse valor para 1024M, e tudo o que faz é levar mais tempo para ocorrer um erro.
Quanto às etapas que eu tomei, tentei desabilitar todo o processamento no lado do servidor e o montei para retornar uma resposta fixa, independentemente da entrada. No entanto, acredito que o problema está no envio real dos dados. Eu até tentei desabilitar o tempo máximo de execução de script para PHP, e ele ainda gera erros.
fonte
ini_set('memory_limit', '256M');
Respostas:
Alterar o
memory_limit
by nãoini_set('memory_limit', '-1');
é uma solução adequada. Por favor, não faça isso.Seu código PHP pode ter um vazamento de memória em algum lugar e você está dizendo ao servidor para usar apenas toda a memória que ele deseja. Você não teria resolvido o problema. Se você monitorar seu servidor, verá que agora está provavelmente usando a maior parte da RAM e até trocando para o disco.
Você provavelmente deve tentar rastrear o código incorreto no seu código e corrigi-lo.
fonte
-1
poderia ser útil apenas em ambientes de desenvolvimento para fins de teste.ini_set('memory_limit', '-1');
substitui o limite de memória PHP padrão .fonte
-1
é um valor que o PHP entende como ilimitado neste contexto.A maneira correta é editar seu
php.ini
arquivo. Editememory_limit
para o seu valor desejado.A partir da sua pergunta
128M
(que é o limite padrão) foi excedida, há algo seriamente errado no seu código, pois não deve demorar muito.Se você sabe por que é preciso muito e deseja permitir que o valor seja definido
memory_limit = 512M
ou superior, você deve ser bom.fonte
A alocação de memória para PHP pode ser ajustada permanentemente ou temporariamente.
Permanentemente
Você pode alterar permanentemente a alocação de memória PHP de duas maneiras.
Se você tiver acesso ao seu
php.ini
arquivo, poderá editar o valor paramemory_limit
o valor desejado.Se você não tiver acesso ao seu
php.ini
arquivo (e o seu host permitir), poderá substituir a alocação de memória pelo seu.htaccess
arquivo. Adicionephp_value memory_limit 128M
(ou seja qual for a alocação desejada).Temporário
Você pode ajustar a alocação de memória em tempo real a partir de um arquivo PHP. Você simplesmente tem o código
ini_set('memory_limit', '128M');
(ou qualquer que seja a alocação desejada). Você pode remover o limite de memória (embora os limites da máquina ou da instância ainda possam se aplicar), definindo o valor como "-1".fonte
É muito fácil obter vazamentos de memória em um script PHP - especialmente se você usar abstração, como um ORM. Tente usar o Xdebug para criar um perfil do seu script e descobrir para onde foi toda essa memória.
fonte
Ao adicionar 22,5 milhões de registros em uma matriz com array_push, eu continuava recebendo erros fatais de "memória esgotada" em cerca de 20 milhões de registros usando
4G
como limite de memória no arquivo php.ini. Para corrigir isso, adicionei a declaraçãona parte superior do arquivo. Agora tudo está funcionando bem. Eu não sei se o PHP tem um vazamento de memória. Esse não é o meu trabalho, nem me importo. Eu só tenho que fazer meu trabalho, e isso funcionou.
O programa é muito simples:
O erro fatal aponta para a linha 3 até eu aumentar o limite de memória, o que eliminou o erro.
fonte
ini_set('memory_limit', '8192M');
?Eu continuava recebendo esse erro, mesmo com
memory_limit
set inphp.ini
, e o valor sendo lido corretamente comphpinfo()
.Alterando-o a partir disso:
Para isso:
Isso corrigiu o problema no PHP 7.
fonte
Quando você vê o erro acima - especialmente se o
(tried to allocate __ bytes)
valor é baixo, isso pode ser um indicador de um loop infinito, como uma função que se chama sem saída:fonte
Depois de ativar essas duas linhas, ele começou a funcionar:
fonte
Você pode corrigir isso corretamente, alterando o
memory_limit
fastcgi / fpm:Mude a memória, como de 128 para 512, veja abaixo
para
fonte
Diretório raiz do seu site:
fonte
Altere o limite de memória no arquivo php.ini e reinicie o Apache. Após o reinício, execute o phpinfo (); função de qualquer arquivo PHP para uma
memory_limit
confirmação de alteração.Limite de memória -1 significa que não há limite de memória definido. Agora está no máximo.
fonte
Para usuários do Drupal, esta resposta de Chris Lane:
funciona, mas precisamos colocá-lo logo após a abertura
no arquivo index.php no diretório raiz do seu site.
fonte
No Drupal 7, você pode modificar o limite de memória no arquivo settings.php localizado na sua pasta sites / padrão. Na linha 260, você verá o seguinte:
Mesmo que suas configurações de php.ini sejam altas o suficiente, você não poderá consumir mais de 128 MB se isso não estiver definido no seu arquivo Drupal settings.php.
fonte
Em vez de alterar o
memory_limit
valor do seuphp.ini
arquivo, se houver uma parte do seu código que possa usar muita memória, você poderá remover omemory_limit
antes dessa seção e substituí-lo depois.fonte
O PHP 5.3+ permite alterar o limite de memória colocando um
.user.ini
arquivo napublic_html
pasta Simplesmente crie o arquivo acima e digite a seguinte linha:Alguns hosts cPanel aceitam apenas esse método.
fonte
Bater página?
(Isso acontece quando o MySQL precisa consultar linhas grandes. Por padrão,
memory_limit
é definido como pequeno, o que era mais seguro para o hardware.)Você pode verificar o status da memória existente do sistema antes de aumentar
php.ini
:Aqui eu a ampliei como a seguir e depois o faço
service httpd restart
para corrigir o problema da página de falha.fonte
free -m
comando para decidir sobre um novo limite de memória?Basta adicionar uma
ini_set('memory_limit', '-1');
linha na parte superior da sua página da web.E você pode definir sua memória conforme sua necessidade no lugar de -1, para
16M
, etc.fonte
Para aqueles que estão coçando a cabeça para descobrir por que diabos essa pequena função deve causar um vazamento de memória, às vezes por um pequeno erro, uma função começa a se chamar recursivamente para sempre.
Por exemplo, uma classe de proxy que tem o mesmo nome para uma função do objeto que o fará proxy.
Às vezes, você pode esquecer de trazer esse pequeno membro realObjec e, como o proxy realmente possui esse
doSomething
método, o PHP não forneceria nenhum erro e, para uma classe grande, ele poderia ficar oculto por alguns minutos para descobrir por que está vazando a memória.fonte
die('here')
seu código e mover essa declaração para ver onde a recursão começa.Ocorreu o erro abaixo ao executar em um conjunto de dados menor do que o que funcionava anteriormente.
Como a busca pela falha me trouxe aqui, pensei em mencionar que nem sempre são as soluções técnicas nas respostas anteriores, mas algo mais simples. No meu caso, foi o Firefox. Antes de executar o programa, ele já estava usando 1.157 MB.
Acontece que eu estava assistindo um vídeo de 50 minutos, um pouco de cada vez, durante um período de dias, e isso estragou tudo. É o tipo de correção que os especialistas corrigem sem nem pensar, mas para mim vale a pena lembrar.
fonte
A execução do script como este (caso cron, por exemplo):
php5 /pathToScript/info.php
produz o mesmo erro.A maneira correta:
php5 -cli /pathToScript/info.php
fonte
Se você estiver executando um VPS (servidor privado virtual) com WHM, poderá descobrir que não possui permissões para editar o PHP.INI diretamente; o sistema deve fazer isso. No painel de controle do host do WHM, vá para Service Configuration → PHP Configuration Editor e modifique
memory_limit
:fonte
Acho útil quando incluir ou exigir
_dbconnection.php_
e_functions.php
nos arquivos realmente processados, em vez de incluir no cabeçalho. O que está incluído em si.Portanto, se o cabeçalho e o rodapé estiverem incluídos, basta incluir todos os seus arquivos funcionais antes da inclusão do cabeçalho.
fonte
Usar
yield
pode ser uma solução também. Consulte Sintaxe do gerador .Em vez de alterar o
PHP.ini
arquivo para um armazenamento de memória maior, às vezes a implementação deyield
um loop interno pode corrigir o problema. O que o rendimento faz é, em vez de descarregar todos os dados de uma vez, ele os lê um por um, economizando muito uso de memória.fonte
PHP.ini
? Não éphp.ini
?Às vezes, esse erro é causado por um bug no código PHP que causa recursões envolvendo manipulação de exceções e possivelmente outras operações. Infelizmente, não consegui criar um pequeno exemplo.
Nestes casos, o que aconteceu várias vezes,
set_time_limit
falha e o navegador continua tentando carregar a saída do PHP, com um loop infinito ou com a mensagem de erro fatal que é o tópico desta pergunta.Reduzindo o tamanho de alocação permitido adicionando
próximo ao início do seu código, você poderá evitar o erro fatal.
Em seguida, você pode ficar com um programa que termina, mas ainda é difícil de depurar.
Nesse ponto, insira
BreakLoop()
chamadas dentro do seu programa para obter controle e descobrir qual loop ou recursão no seu programa está causando o problema.A definição de BreakLoop é a seguinte:
O argumento $ LoopSite pode ser o nome de uma função no seu código. Não é realmente necessário, pois a mensagem de erro que você receberá apontará para a linha que contém a chamada BreakLoop ().
fonte
No meu caso, foi um breve problema com a forma como uma função foi escrita. Um vazamento de memória pode ser causado pela atribuição de um novo valor à variável de entrada de uma função, por exemplo:
fonte
Quando removi as seguintes linhas do meu código, tudo funcionou bem!
Essas linhas foram incluídas em todos os arquivos que eu estava executando. Ao executar os arquivos um por um, tudo funcionou bem, mas ao executar todos os arquivos juntos, tive o problema de vazamento de memória. De alguma forma, o "include_once" não está incluindo as coisas uma vez, ou estou fazendo algo errado ...
fonte
set_include_path(get_include_path() . get_include_path().'/phpseclib');
Isso adicionará o caminho '/ phpseclib' uma vez para cada arquivo que tem a linha ... para que ele possa ser adicionado várias vezes! Eu sugiro colocá-lo em um arquivo de configurações einclude_once
o arquivo de configurações.