Existe uma função no PHP (ou uma extensão do PHP) para descobrir quanta memória usa uma determinada variável? sizeof
apenas me diz o número de elementos / propriedades.
memory_get_usage
ajuda na medida em que me dá o tamanho da memória usado por todo o script. Existe uma maneira de fazer isso para uma única variável?
Observe que isso está em uma máquina de desenvolvimento, portanto, carregar extensões ou ferramentas de depuração é viável.
Respostas:
Você provavelmente precisa de um Memory Profiler. Eu coletei informações para ASSIM, mas copiei algumas coisas importantes que podem ajudá-lo também.
Como você provavelmente sabe, o Xdebug abandonou o suporte a perfis de memória desde a versão 2. *. Pesquise a string "funções removidas" aqui: http://www.xdebug.org/updates.php
Outras opções do Profiler
php-memory-profiler
https://github.com/arnaud-lb/php-memory-profiler . Isso é o que fiz no meu servidor Ubuntu para ativá-lo:
E então no meu código:
Finalmente abra o
callgrind.out
arquivo com o KCachegrindUsando Google gperftools (recomendado!)
Em primeiro lugar, instale o Google gperftools baixando o pacote mais recente aqui: https://code.google.com/p/gperftools/
Então, como sempre:
Agora em seu código:
Em seguida, abra seu terminal e execute:
pprof criará uma nova janela em sua sessão de navegador existente com algo como mostrado abaixo:
Xhprof + Xhgui (o melhor na minha opinião para o perfil de CPU e memória)
Com o Xhprof e o Xhgui, você também pode traçar o perfil do uso da CPU ou apenas do uso da memória, se esse for o seu problema no momento. É uma solução muito completa, dá-lhe total controlo e os logs podem ser escritos tanto no mongo como no sistema de ficheiros.
Para mais detalhes veja aqui .
Fogo Preto
Blackfire é um profiler PHP da SensioLabs, os caras do Symfony2 https://blackfire.io/
Se você usar o fantoche para configurar sua máquina virtual, ficará feliz em saber que é compatível ;-)
Xdebug e rastreamento de uso de memória
XDEBUG2 é uma extensão para PHP. O Xdebug permite que você registre todas as chamadas de função, incluindo parâmetros e valores de retorno para um arquivo em formatos diferentes. Existem três formatos de saída. Um deve ser um rastreamento legível por humanos, outro é mais adequado para programas de computador, pois é mais fácil de analisar, e o último usa HTML para formatar o rastreamento. Você pode alternar entre os dois formatos diferentes com a configuração. Um exemplo estaria disponível aqui
para p
forp simples, não intrusivo, orientado à produção, criador de perfil de PHP. Alguns dos recursos são:
medição de tempo e memória alocada para cada função
utilização do CPU
arquivo e número da linha da chamada de função
saída como formato de evento de rastreamento do Google
legenda de funções
agrupamento de funções
aliases de funções (útil para funções anônimas)
DBG
DBG é um depurador de php completo, uma ferramenta interativa que ajuda a depurar scripts de php. Funciona em um servidor WEB de produção e / ou desenvolvimento e permite depurar seus scripts local ou remotamente, a partir de um IDE ou console e seus recursos são:
Depuração remota e local
Ativação explícita e implícita
Pilha de chamadas, incluindo chamadas de função, chamadas de método estático e dinâmico, com seus parâmetros
Navegação pela pilha de chamadas com capacidade de avaliar variáveis em locais correspondentes (aninhados)
Funcionalidade Step in / Step out / Step over / Run to cursor
Breakpoints condicionais
Pontos de interrupção globais
Registro de erros e avisos
Várias sessões simultâneas para depuração paralela
Suporte para interfaces GUI e CLI
Redes IPv6 e IPv4 suportadas
Todos os dados transferidos pelo depurador podem ser protegidos opcionalmente com SSL
fonte
Não há uma maneira direta de obter o uso de memória de uma única variável, mas, como sugeriu Gordon, você pode usar
memory_get_usage
. Isso retornará a quantidade total de memória alocada, para que você possa usar uma solução alternativa e medir o uso antes e depois de obter o uso de uma única variável. Isso é um pouco hackeado, mas deve funcionar.Observe que este não é, de forma alguma, um método confiável, você não pode ter certeza de que nada mais tocará na memória ao atribuir a variável, então isso deve ser usado apenas como uma aproximação.
Você pode realmente transformar isso em uma função criando uma cópia da variável dentro da função e medindo a memória usada. Não testei isso, mas, em princípio, não vejo nada de errado nisso:
fonte
$tmp = $var
criará uma cópia superficial. Isso não alocará mais memória até que $ tmp seja modificado.$tmp = unserialize(serialize($var))
; Isso combinaria a abordagem de Aistina acima.$var
já é uma cópia superficial ou referência do que foi passado para a função, você não precisa$tmp
, mas pode reatribuir a$var
. Isso salva a referência interna de$tmp
a$var
.$tmp
de$var
?Não, não há. Mas você pode
serialize($var)
e verificar ostrlen
do resultado para uma aproximação.fonte
strlen(serialize(array(1,2,3)))
é 30.Em resposta à resposta de Tatu Ulmanens:
Deve-se notar que
$start_memory
ele próprio ocupará memória (PHP_INT_SIZE * 8
).Portanto, toda a função deve ser:
Desculpe adicionar isso como uma resposta extra, mas ainda não posso comentar uma resposta.
Atualização: O * 8 não é definitivo. Pode depender aparentemente da versão php e possivelmente de 64/32 bits.
fonte
* 8
? Obrigado!PHP_INT_SIZE
bytes, masPHP_INT_SIZE*8
. Você pode tentar isso chamando esta função, ela deve retornar 0:function sizeofvar() { $start_memory = memory_get_usage(); return memory_get_usage() - $start_memory - PHP_INT_SIZE*8; }
8
não parece constante. Seguindo sua função de comentário em meu sistema dev (PHP 5.6.19), ele retorna-16
. Além disso, curiosamente, a partir dephp -a
, chamar as duas linhas da função fornece vários valores diferentes.Vejo:
memory_get_usage()
- Retorna a quantidade de memória alocada para PHPmemory_get_peak_usage()
- Retorna o pico de memória alocado pelo PHPObserve que isso não fornecerá o uso de memória de uma variável específica. Mas você pode fazer chamadas para essas funções antes e depois de atribuir a variável e, em seguida, comparar os valores. Isso deve dar uma ideia da memória usada.
Você também pode dar uma olhada na extensão PECL Memtrack , embora a documentação seja um pouco deficiente, se não para dizer, virtualmente inexistente.
fonte
Você pode optar por calcular a diferença de memória em um valor de retorno de chamada. É uma solução mais elegante disponível no PHP 5.3+.
fonte
Você não pode calcular retrospectivamente a pegada exata de uma variável, pois duas variáveis podem compartilhar o mesmo espaço alocado na memória
Vamos tentar compartilhar memória entre dois arrays, vemos que alocar o segundo array custa metade da memória do primeiro. Quando removemos o primeiro, quase toda a memória ainda é usada pelo segundo.
Portanto, não podemos concluir que o segundo array usa metade da memória, pois torna-se falso quando removemos o primeiro.
Para uma visão completa sobre como a memória é alocada no PHP e para qual uso, sugiro que você leia o seguinte artigo: Qual o tamanho real dos arrays (e valores) do PHP? (Dica: GRANDE!)
O Reference Counting Basics na documentação do PHP também contém muitas informações sobre o uso de memória e contagem de referências para segmentos de dados compartilhados.
As diferentes soluções expostas aqui são boas para aproximações, mas nenhuma pode lidar com o gerenciamento sutil de memória PHP.
Se você quiser o espaço recém-alocado após uma atribuição, terá que usá-lo
memory_get_usage()
antes e depois da alocação, pois usá-lo com uma cópia lhe dá uma visão errônea da realidade.Lembre-se de que se você quiser armazenar o resultado da primeira
memory_get_usage()
, a variável já deve existir antes ememory_get_usage()
deve ser chamada outra vez, e também todas as outras funções.Se você quiser ecoar como no exemplo acima, seu buffer de saída já deve estar aberto para evitar a memória de contabilidade necessária para abrir o buffer de saída.
Se você quiser contar com uma função para calcular o espaço necessário para armazenar uma cópia de uma variável, o código a seguir cuida de diferentes otimizações:
Observe que o tamanho do nome da variável é importante na memória alocada.
Uma variável tem um tamanho básico definido pela estrutura interna C usada no código-fonte do PHP. Este tamanho não varia no caso de números. Para strings, adicionaria o comprimento da string.
Se não levarmos em consideração a inicialização do nome da variável, já sabemos quanto uma variável usa (no caso de números e strings):
(esses números podem mudar dependendo da versão do PHP)
Você deve arredondar para um múltiplo de 4 bytes devido ao alinhamento da memória. Se a variável estiver no espaço global (não dentro de uma função), ela também alocará mais 64 bytes.
Portanto, se você quiser usar um dos códigos dentro desta página, você deve verificar se o resultado usando alguns casos de teste simples (strings ou números) correspondem a esses dados levando em consideração cada uma das indicações neste artigo ($ _GLOBAL array, primeira chamada de função, buffer de saída, ...)
fonte
zvalue
,is_ref
e copiar-on-write. Obrigado.Tive um problema semelhante, e a solução que usei foi gravar a variável em um arquivo e executar filesize () nele. Mais ou menos assim (código não testado):
Esta solução não é terrivelmente rápida porque envolve E / S de disco, mas deve fornecer algo muito mais exato do que os truques de memory_get_usage. Depende apenas de quanta precisão você precisa.
fonte
strlen
seria mais fácil.Nunca tentei, mas os rastreamentos de Xdebug com xdebug.collect_assignment s podem ser suficientes.
fonte
fonte
O script a seguir mostra o uso total de memória de uma única variável.
Veja isso
http://www.phpzag.com/how-much-memory-do-php-variables-use/
fonte