Qual perfilador de memória de Python é recomendado? [fechadas]

671

Quero saber o uso de memória do meu aplicativo Python e quero especificamente saber quais blocos / partes de código ou objetos estão consumindo mais memória. A pesquisa do Google mostra que uma comercial é o Python Memory Validator (somente Windows).

E os de código aberto são PySizer e Heapy .

Eu não tentei ninguém, então eu queria saber qual é o melhor, considerando:

  1. Dá mais detalhes.

  2. Eu tenho que fazer poucas ou nenhuma alteração no meu código.

Anurag Uniyal
fonte
2
Para encontrar as fontes dos vazamentos, recomendo o objgraph.
pi.
9
@MikeiLL Há um lugar para perguntas como estas: Recomendações de Software
Poik 5/15/15
2
Isso está acontecendo com frequência suficiente para que possamos migrar uma pergunta para outro fórum.
Zabumba
Uma dica: se alguém usa o gae to e deseja verificar o uso da memória - é uma grande dor de cabeça, porque essas ferramentas não produziram nada ou o evento não foi iniciado. Se você quiser testar algo pequeno, mova a função que deseja testar para o arquivo separado e execute-o sozinho.
alexche8
4
Eu recomendo pympler
zzzeek

Respostas:

288

Heapy é bastante simples de usar. Em algum momento do seu código, você deve escrever o seguinte:

from guppy import hpy
h = hpy()
print(h.heap())

Isso fornece uma saída como esta:

Partition of a set of 132527 objects. Total size = 8301532 bytes.
Index  Count   %     Size   % Cumulative  % Kind (class / dict of class)
0  35144  27  2140412  26   2140412  26 str
1  38397  29  1309020  16   3449432  42 tuple
2    530   0   739856   9   4189288  50 dict (no owner)

Você também pode descobrir de onde os objetos são referenciados e obter estatísticas sobre isso, mas de alguma forma os documentos são um pouco esparsos.

Também existe um navegador gráfico, escrito em Tk.

Torsten Marek
fonte
24
Se você estiver em Python 2.7 você pode precisar a versão tronco dele: sourceforge.net/tracker/... ,pip install https://guppy-pe.svn.sourceforge.net/svnroot/guppy-pe/trunk/guppy
James Snyder
27
Os documentos pesados ​​... não são bons. Mas achei este post de blog muito útil para começar: smira.ru/wp-content/uploads/2011/08/heapy.html
Joe Shaw
4
Observe que o heapy não inclui memória alocada em extensões python. Se alguém criou um mecanismo para facilitar a inclusão de boost::pythonobjetos, seria bom ver alguns exemplos!
31714 amos
34
A partir de 06/07/2014, o guppy não suporta Python 3.
Quentin Pradet
5
Existe um fork do guppy que suporta o Python 3 chamado guppy3.
David Foster
385

Como ninguém o mencionou, aponto para o meu módulo memory_profiler, que é capaz de imprimir relatórios linha a linha do uso de memória e funciona no Unix e no Windows (precisa de psutil neste último). A saída não é muito detalhada, mas o objetivo é fornecer uma visão geral de onde o código está consumindo mais memória e não uma análise exaustiva dos objetos alocados.

Depois de decorar sua função @profilee executar seu código com o -m memory_profilersinalizador, ele imprimirá um relatório linha por linha como este:

Line #    Mem usage  Increment   Line Contents
==============================================
     3                           @profile
     4      5.97 MB    0.00 MB   def my_func():
     5     13.61 MB    7.64 MB       a = [1] * (10 ** 6)
     6    166.20 MB  152.59 MB       b = [2] * (2 * 10 ** 7)
     7     13.61 MB -152.59 MB       del b
     8     13.61 MB    0.00 MB       return a
Fabian Pedregosa
fonte
1
Para meu caso de uso - um script simples de manipulação de imagem, não um sistema complexo, que deixou alguns cursores abertos - essa era a melhor solução. Muito simples de descobrir e descobrir o que está acontecendo, com o mínimo de sujeira adicionada ao seu código. Perfeito para soluções rápidas e provavelmente ótimo para outras aplicações também.
Driftcatcher
10
Acho que memory_profiler é realmente simples e fácil de usar. Eu quero criar perfis por linha e não por objeto. Obrigado por escrever.
tommy.carstensen
1
@FabianPedregosa como o memory_profiler de dose lida com loops, ele pode identificar o número da iteração do loop?
Glen Fletcher
3
Ele identifica loops apenas implicitamente quando tenta relatar o valor linha por linha e encontra linhas duplicadas. Nesse caso, ele terá apenas o máximo de todas as iterações.
Fabian Pedregosa
1
@FabianPedregosa memory_profilerBuffer sua saída? Posso estar fazendo algo errado, mas parece que, em vez de despejar o perfil de uma função quando ela é concluída, aguarda o término do script.
Greenstick 30/07/2018
80

Eu recomendo Dowser . É muito fácil de configurar e você precisa de zero alterações no seu código. Você pode visualizar a contagem de objetos de cada tipo ao longo do tempo, visualizar a lista de objetos ativos, ver referências a objetos ativos, tudo a partir da interface da web simples.

# memdebug.py

import cherrypy
import dowser

def start(port):
    cherrypy.tree.mount(dowser.Root())
    cherrypy.config.update({
        'environment': 'embedded',
        'server.socket_port': port
    })
    cherrypy.server.quickstart()
    cherrypy.engine.start(blocking=False)

Você importa o memdebug e chama o memdebug.start. Isso é tudo.

Eu não tentei o PySizer ou o Heapy. Eu apreciaria as opiniões dos outros.

ATUALIZAR

O código acima é para CherryPy 2.X, CherryPy 3.Xo server.quickstartmétodo foi removido e engine.startnão recebe o blockingsinalizador. Então, se você estiver usandoCherryPy 3.X

# memdebug.py

import cherrypy
import dowser

def start(port):
    cherrypy.tree.mount(dowser.Root())
    cherrypy.config.update({
        'environment': 'embedded',
        'server.socket_port': port
    })
    cherrypy.engine.start()
sanxiyn
fonte
3
mas é apenas para cherrypy, como usá-lo com um script simples?
Anurag Uniyal 21/09/08
13
Não é para CherryPy. Pense no CherryPy como um kit de ferramentas da GUI.
sanxiyn 21/09/08
1
fwiw, a página pysizer pysizer.8325.org parece recomendar Heapy, que ele diz que é semelhante
Jacob Gabrielson
6
Há uma porta WSGI genérico de Dowser chamado Dozer, que você pode usar com outros servidores web, bem como: pypi.python.org/pypi/Dozer
Joe Shaw
2
cherrypy 3.1 cherrypy.server.quickstart removido (), então é só usar cherrypy.engine.start ()
MatsLindh
66

Considere o objetivo biblioteca (consultehttp://www.lshift.net/blog/2008/11/14/tracing-python-memory-leaks para um exemplo de caso de uso).

Charles Duffy
fonte
7
O objgraph me ajudou a resolver um problema de vazamento de memória que eu estava enfrentando hoje. objgraph.show_growth () foi particularmente útil
Ngure Nyaga 11/11
1
Eu também achei o objgraph realmente útil. Você pode fazer coisas como objgraph.by_type('dict')entender de onde dictvêm todos esses objetos inesperados .
Dino
18

Muppy é (mais um) Profiler de uso de memória para Python. O foco deste conjunto de ferramentas é colocado na identificação de vazamentos de memória.

Muppy tenta ajudar os desenvolvedores a identificar vazamentos de memória de aplicativos Python. Permite o rastreamento do uso da memória durante o tempo de execução e a identificação de objetos que estão vazando. Além disso, são fornecidas ferramentas que permitem localizar a origem dos objetos não liberados.

Serrano
fonte
13

Estou desenvolvendo um criador de perfil de memória para Python chamado memprof:

http://jmdana.github.io/memprof/

Permite registrar e plotar o uso de memória de suas variáveis ​​durante a execução dos métodos decorados. Você apenas precisa importar a biblioteca usando:

from memprof import memprof

E decore seu método usando:

@memprof

Este é um exemplo de como os gráficos se parecem:

insira a descrição da imagem aqui

O projeto está hospedado no GitHub:

https://github.com/jmdana/memprof

jmdana
fonte
3
Como eu uso isso? O que é a, b, c?
tommy.carstensen
@ tommy.carstensen a, be csão os nomes das variáveis. Você pode encontrar a documentação em github.com/jmdana/memprof . Se você tiver alguma dúvida, sinta-se à vontade para enviar um problema no github ou enviar um email para a lista de discussão que pode ser encontrada na documentação.
Jmdana 09/09
12

Eu achei as melias muito mais funcionais que o Heapy ou o PySizer. Se você estiver executando um aplicativo Web wsgi, o Dozer é um bom pacote de middleware da Dowser

Calen Pennington
fonte
8

Experimente também o projeto pytracemalloc que fornece o uso da memória por número de linha do Python.

EDIT (2014/04): Agora ele possui uma interface gráfica Qt para analisar snapshots.

Haypo
fonte
4
tracemallocagora faz parte da biblioteca padrão do python. Veja docs.python.org/3/library/tracemalloc.html
Dan Milon