Memray é um criador de perfil de memória para Python. Ele pode rastrear alocações de memória no código Python, em módulos de extensão nativos e no próprio interpretador Python. Ele pode gerar vários tipos diferentes de relatórios para ajudá-lo a analisar os dados de uso de memória capturados. Embora comumente usado como uma ferramenta CLI, ele também pode ser usado como uma biblioteca para executar tarefas de criação de perfil mais refinadas.
Recursos notáveis:
Memray pode ajudar com os seguintes problemas:
Nota Memray funciona apenas em Linux e MacOS e não pode ser instalado em outras plataformas.
Estamos constantemente buscando feedback de nossa incrível comunidade ❤️. Se você usou o Memray para resolver um problema, criar o perfil de um aplicativo, encontrar um vazamento de memória ou qualquer outra coisa, informe-nos! Adoraríamos ouvir sobre sua experiência e como Memray o ajudou.
Por favor, considere escrever sua história na página de discussão de Histórias de Sucesso.
Realmente faz diferença!
Memray requer Python 3.7+ e pode ser facilmente instalado usando as ferramentas de empacotamento Python mais comuns. Recomendamos instalar a versão estável mais recente do PyPI com pip:
python3 -m pip install memray
Observe que o Memray contém uma extensão C, portanto as versões são distribuídas como rodas binárias, assim como o código-fonte. Se uma roda binária não estiver disponível para o seu sistema (Linux x86/x64 ou macOS), você precisará garantir que todas as dependências sejam satisfeitas no sistema onde você está fazendo a instalação.
Se você deseja construir o Memray a partir do código-fonte, você precisa das seguintes dependências binárias em seu sistema:
Verifique seu gerenciador de pacotes sobre como instalar essas dependências (por exemplo apt-get install build-essential python3-dev libdebuginfod-dev libunwind-dev liblz4-dev
em sistemas baseados em Debian ou brew install lz4
em MacOS). Observe que pode ser necessário ensinar ao compilador onde encontrar os arquivos de cabeçalho e de biblioteca das dependências. Por exemplo, no MacOS com brew
você pode precisar executar:
export CFLAGS= " -I $( brew --prefix lz4 ) /include " LDFLAGS= " -L $( brew --prefix lz4 ) /lib -Wl,-rpath, $( brew --prefix lz4 ) /lib "
antes de instalar memray
. Verifique a documentação do seu gerenciador de pacotes para saber a localização dos arquivos de cabeçalho e biblioteca para obter informações mais detalhadas.
Se estiver desenvolvendo no MacOS, você também precisará definir o destino de implantação.
export MACOSX_DEPLOYMENT_TARGET=10.14
Depois de instalar as dependências binárias, você pode clonar o repositório e seguir com o processo normal de construção:
git clone [email protected]:bloomberg/memray.git memray
cd memray
python3 -m venv ../memray-env/ # just an example, put this wherever you want
source ../memray-env/bin/activate
python3 -m pip install --upgrade pip
python3 -m pip install -e . -r requirements-test.txt -r requirements-extra.txt
Isso instalará o Memray no ambiente virtual em modo de desenvolvimento (o -e
do último comando pip install
).
Se você planeja contribuir de volta, você deve instalar os ganchos de pré-commit:
pre-commit install
Isso garantirá que sua contribuição passe em nossas verificações de linting.
Você pode encontrar a documentação mais recente disponível aqui.
Existem muitas maneiras de usar o Memray. A maneira mais fácil é usá-lo como uma ferramenta de linha de comando para executar seu script, aplicativo ou biblioteca.
usage: memray [-h] [-v] {run,flamegraph,table,live,tree,parse,summary,stats} ...
Memory profiler for Python applications
Run `memray run` to generate a memory profile report, then use a reporter command
such as `memray flamegraph` or `memray table` to convert the results into HTML.
Example:
$ python3 -m memray run -o output.bin my_script.py
$ python3 -m memray flamegraph output.bin
positional arguments:
{run,flamegraph,table,live,tree,parse,summary,stats}
Mode of operation
run Run the specified application and track memory usage
flamegraph Generate an HTML flame graph for peak memory usage
table Generate an HTML table with all records in the peak memory usage
live Remotely monitor allocations in a text-based interface
tree Generate a tree view in the terminal for peak memory usage
parse Debug a results file by parsing and printing each record in it
summary Generate a terminal-based summary report of the functions that allocate most memory
stats Generate high level stats of the memory usage in the terminal
optional arguments:
-h, --help Show this help message and exit
-v, --verbose Increase verbosity. Option is additive and can be specified up to 3 times
-V, --version Displays the current version of Memray
Please submit feedback, ideas, and bug reports by filing a new issue at https://github.com/bloomberg/memray/issues
Para usar o Memray sobre um script ou um único arquivo python, você pode usar:
python3 -m memray run my_script.py
Se você normalmente executa seu aplicativo com python3 -m my_module
, você pode usar o sinalizador -m
com memray run
:
python3 -m memray run -m my_module
Você também pode invocar o Memray como uma ferramenta de linha de comando sem precisar usar -m
para invocá-lo como um módulo:
memray run my_script.py
memray run -m my_module
A saída será um arquivo binário (como memray-my_script.2369.bin
) que você pode analisar de diferentes maneiras. Uma maneira é usar o comando memray flamegraph
para gerar um gráfico em degradê:
memray flamegraph my_script.2369.bin
Isso produzirá um arquivo HTML com um gráfico em chamas do uso de memória que você pode inspecionar com seu navegador favorito. Existem vários outros repórteres que você pode usar para gerar outros tipos de relatórios, alguns deles gerando saída baseada em terminal e outros gerando arquivos HTML. Aqui está um exemplo de um flamegraph Memray:
Se você deseja uma maneira fácil e conveniente de usar memray
em seu conjunto de testes, considere usar o pytest-memray. Uma vez instalado, este plugin pytest permite simplesmente adicionar --memray
à invocação da linha de comando:
pytest --memray tests/
E receberá automaticamente um relatório como este:
python3 -m pytest tests --memray
=============================================================================================================================== test session starts ================================================================================================================================
platform linux -- Python 3.8.10, pytest-6.2.4, py-1.10.0, pluggy-0.13.1
rootdir: /mypackage, configfile: pytest.ini
plugins: cov-2.12.0, memray-0.1.0
collected 21 items
tests/test_package.py ..................... [100%]
================================================================================================================================= MEMRAY REPORT ==================================================================================================================================
Allocations results for tests/test_package.py::some_test_that_allocates
? Total memory allocated: 24.4MiB
? Total allocations: 33929
Histogram of allocation sizes: |▂ █ |
? Biggest allocating functions:
- parse:/opt/bb/lib/python3.8/ast.py:47 -> 3.0MiB
- parse:/opt/bb/lib/python3.8/ast.py:47 -> 2.3MiB
- _visit:/opt/bb/lib/python3.8/site-packages/astroid/transforms.py:62 -> 576.0KiB
- parse:/opt/bb/lib/python3.8/ast.py:47 -> 517.6KiB
- __init__:/opt/bb/lib/python3.8/site-packages/astroid/node_classes.py:1353 -> 512.0KiB
Você também pode usar alguns dos marcadores incluídos para fazer com que os testes falhem se a execução do referido teste alocar mais memória do que o permitido:
@ pytest . mark . limit_memory ( "24 MB" )
def test_foobar ():
# do some stuff that allocates memory
Para saber mais sobre como o plugin pode ser usado e configurado confira a documentação do plugin.
Memray oferece suporte ao rastreamento de funções C/C++ nativas, bem como funções Python. Isso pode ser especialmente útil ao criar perfis de aplicativos que possuem extensões C (como numpy
ou pandas
), pois fornece uma visão holística de quanta memória é alocada pela extensão e quanto é alocada pelo próprio Python.
Para ativar o rastreamento nativo, você precisa fornecer o argumento --native
ao usar o subcomando run
:
memray run --native my_script.py
Isso adicionará automaticamente informações nativas ao arquivo de resultado e será usado automaticamente por qualquer repórter (como o flamegraph ou repórteres de mesa). Isso significa que em vez de ver isso nos flamegraphs:
Agora você poderá ver o que está acontecendo nas chamadas do Python:
Os repórteres exibem frames nativos em uma cor diferente dos frames Python. Eles também podem ser distinguidos observando a localização do arquivo em um quadro (os quadros Python geralmente serão gerados a partir de arquivos com extensão .py, enquanto os quadros nativos serão gerados a partir de arquivos com extensões como .c, .cpp ou .h).
O modo ao vivo do Memray executa um script ou módulo em uma interface baseada em terminal que permite inspecionar interativamente o uso de memória enquanto ele é executado. Isso é útil para depurar scripts ou módulos que demoram muito para serem executados ou que exibem vários padrões de memória complexos. Você pode usar a opção --live
para executar o script ou módulo no modo ao vivo:
memray run --live my_script.py
ou se você deseja executar um módulo:
memray run --live -m my_module
Isso mostrará a seguinte interface TUI em seu terminal:
Os resultados são exibidos em ordem decrescente da memória total alocada por uma função e das subfunções chamadas por ela. Você pode alterar a ordem com os seguintes atalhos de teclado:
t (padrão): Classificar por memória total
o: Classificar por memória própria
a: Classificar por contagem de alocação
Na maioria dos terminais você também pode clicar nos botões "Classificar por Total", "Classificar por Próprio" e "Classificar por Alocações" no rodapé.
O título da coluna classificada está sublinhado.
Por padrão, o comando live apresentará o thread principal do programa. Você pode examinar diferentes threads do programa pressionando as teclas maior que e menor que, <
e >
. Na maioria dos terminais você também pode clicar nos botões "Tópico Anterior" e "Próximo Tópico" no rodapé.
Além de rastrear processos Python a partir de uma CLI usando memray run
, também é possível habilitar programaticamente o rastreamento dentro de um programa Python em execução.
import memray
with memray . Tracker ( "output_file.bin" ):
print ( "Allocations will be tracked until the with block ends" )
Para obter detalhes, consulte a documentação da API.
Memray é licenciado pelo Apache-2.0, conforme encontrado no arquivo LICENSE.
Este projeto adotou um Código de Conduta. Se você tiver alguma dúvida sobre o Código ou sobre o comportamento vivenciado no projeto, entre em contato conosco pelo e-mail [email protected].
Se você acredita ter identificado uma vulnerabilidade de segurança neste projeto, envie um e-mail para a equipe do projeto em [email protected], detalhando o problema suspeito e quaisquer métodos que você encontrou para reproduzi-lo.
NÃO abra um problema no repositório GitHub, pois preferimos manter os relatórios de vulnerabilidade privados até que tenhamos a oportunidade de revisá-los e resolvê-los.
Agradecemos suas contribuições para nos ajudar a melhorar e ampliar este projeto!
Abaixo você encontrará alguns passos básicos necessários para poder contribuir com o projeto. Se você tiver alguma dúvida sobre esse processo ou qualquer outro aspecto da contribuição para um projeto de código aberto da Bloomberg, sinta-se à vontade para enviar um e-mail para [email protected] e responderemos suas perguntas o mais rápido possível.
Como este projeto é distribuído sob os termos de uma licença de código aberto, as contribuições feitas por você são licenciadas sob os mesmos termos. Para que possamos aceitar suas contribuições, precisaremos de sua confirmação explícita de que você é capaz e deseja fornecê-las sob estes termos, e o mecanismo que usamos para fazer isso é chamado de Certificado de Origem do Desenvolvedor (DCO). . Isso é muito semelhante ao processo usado pelo kernel Linux, Samba e muitos outros grandes projetos de código aberto.
Para participar sob estes termos, tudo o que você deve fazer é incluir uma linha como a seguinte como a última linha da mensagem de commit para cada commit em sua contribuição:
Signed-Off-By: Random J. Developer <[email protected]>
A maneira mais simples de fazer isso é adicionar -s
ou --signoff
ao comando git commit
.
Você deve usar seu nome verdadeiro (desculpe, sem pseudônimos e sem contribuições anônimas).