跳转到主要内容

Python应用程序的内存分析器

项目描述


OS Linux OS MacOS PyPI - Python Version PyPI - Implementation PyPI PyPI - Downloads Conda Version Tests Code Style

Memray output

Memray是Python的内存分析器。它可以追踪Python代码、本地扩展模块和Python解释器本身的内存分配。它可以生成几种不同类型的报告,帮助您分析捕获的内存使用数据。虽然通常用作CLI工具,但它也可以用作库以执行更细致的分析任务。

显著功能

  • 🕵️‍♀️ 追踪每个函数调用,以便可以准确地表示调用栈,与采样分析器不同。
  • ℭ 也处理C/C++库中的本地调用,因此结果中包含整个调用栈。
  • 🏎️ 极快!分析略微减慢应用程序。跟踪本地代码会稍微慢一些,但可以根据需要启用或禁用。
  • 📈 Memray 可以生成关于收集到的内存使用数据的各种报告,例如火焰图。
  • 🧵 与 Python 线程兼容。
  • 👽🧵 与原生线程兼容(例如 C 扩展中的 C++ 线程)。

Memray 可帮助解决以下问题

  • 分析应用程序中的分配,以帮助发现高内存使用的根源。
  • 查找内存泄漏。
  • 查找代码中的热点,这些热点会导致大量分配。

注意 Memray 仅支持 Linux 和 MacOS,无法安装在其他平台上。

帮助我们改进 Memray!

我们一直在寻找来自我们出色的社区的反馈 ❤️。如果您已使用 Memray 解决问题、分析应用程序、查找内存泄漏或任何其他事情,请告诉我们!我们很乐意了解您的经验和 Memray 如何帮助您。

请考虑在 成功故事讨论页面 上撰写您的经历。

这确实有很大差别!

安装

Memray 需要 Python 3.7+,并且可以使用大多数常见的 Python 打包工具轻松安装。我们建议从 PyPI 安装最新稳定版本,使用 pip 进行安装

    python3 -m pip install memray

请注意,Memray 包含一个 C 扩展,因此发行版以二进制轮和源代码的形式提供。如果您的系统(Linux x86/x64 或 MacOS)没有提供二进制轮,您需要确保在安装过程中满足所有依赖项。

从源代码构建

如果您希望从源代码构建 Memray,您需要在您的系统中安装以下二进制依赖项

  • libdebuginfod-dev(适用于 Linux)
  • libunwind(适用于 Linux)
  • liblz4

检查您的包管理器了解如何安装这些依赖项(例如,在基于 Debian 的系统中使用 apt-get install build-essential python3-dev libdebuginfod-dev libunwind-dev liblz4-dev,或在 MacOS 中使用 brew install lz4)。请注意,您可能需要教编译器在哪里找到依赖项的头文件和库文件。例如,在 MacOS 中使用 brew,您可能需要在安装 memray 之前运行

export CFLAGS="-I$(brew --prefix lz4)/include" LDFLAGS="-L$(brew --prefix lz4)/lib -Wl,-rpath,$(brew --prefix lz4)/lib"

。检查您的包管理器的文档以了解头文件和库文件的位置以获取更多信息。

如果您在 MacOS 上构建,您还需要设置部署目标。

export MACOSX_DEPLOYMENT_TARGET=10.14

一旦安装了二进制依赖项,您可以克隆存储库并按照正常的构建过程进行

git clone git@github.com: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

这将将在开发模式下安装 Memray 到虚拟环境中(最后 pip install 命令中的 -e)。

如果您计划做出贡献,您应该安装预提交钩子

pre-commit install

这将确保您的贡献通过我们的 linting 检查。

文档

您可以在 此处 找到最新文档。

用法

使用 Memray 有很多方法。最简单的方法是将其用作命令行工具来运行您的脚本、应用程序或库。

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

要使用 Memray 运行脚本或单个 Python 文件,您可以使用

python3 -m memray run my_script.py

如果您通常使用 python3 -m my_module 运行应用程序,您可以使用 -m 标志与 memray run 一起使用

python3 -m memray run -m my_module

您还可以直接作为命令行工具调用 Memray,而不需要使用 -m 来调用它作为模块

memray run my_script.py
memray run -m my_module

输出将是一个二进制文件(如 memray-my_script.2369.bin),您可以用不同的方式进行分析。一种方式是使用 memray flamegraph 命令生成火焰图

memray flamegraph my_script.2369.bin

这将生成一个包含内存使用火焰图的 HTML 文件,您可以使用您喜欢的浏览器进行检查。您可以使用多个其他报告器生成其他类型的报告,其中一些生成基于终端的输出,而另一些生成 HTML 文件。以下是一个 Memray 火焰图的示例

Pytest 插件

如果您想在测试套件中方便地使用 memray,可以考虑使用 pytest-memray。安装后,此 pytest 插件允许您简单地添加 --memray 到命令行调用中。

pytest --memray tests/

然后会自动获得如下报告

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

您还可以使用一些包含的标记,如果测试执行分配的内存超过允许量,则使测试失败

@pytest.mark.limit_memory("24 MB")
def test_foobar():
    # do some stuff that allocates memory

要了解更多关于插件的使用和配置,请查看 插件文档

原生模式

Memray 支持跟踪原生 C/C++ 函数以及 Python 函数。当分析具有 C 扩展(如 numpypandas)的应用程序时,这特别有用,因为它可以全面了解扩展分配了多少内存以及 Python 本身分配了多少内存。

要激活原生跟踪,需要在使用 run 子命令时提供 --native 参数

memray run --native my_script.py

这将在结果文件中自动添加原生信息,并且它将被任何报告器(如火焰图报告器或表格报告器)自动使用。这意味着您将不再在火焰图中看到以下内容

您现在将能够看到 Python 调用内部发生的事情

报告器以不同于 Python 帧的颜色显示原生帧。您还可以通过查看帧中的文件位置来区分它们(Python 帧通常由具有 .py 扩展名的文件生成,而原生帧由具有 .c、.cpp 或 .h 扩展名的文件生成)。

实时模式

Memray output

Memray 的实时模式在基于终端的界面中运行脚本或模块,允许您在运行过程中交互式检查其内存使用情况。这对于调试运行时间较长或表现出多种复杂内存模式的脚本或模块非常有用。您可以使用 --live 选项以实时模式运行脚本或模块

    memray run --live my_script.py

或者如果您想执行一个模块

    memray run --live -m my_module

这将在您的终端中显示以下 TUI 界面

排序结果

结果按函数及其调用的子函数分配的总内存量降序显示。您可以使用以下键盘快捷键更改排序

  • t(默认):按总内存排序

  • o:按自用内存排序

  • a:按分配计数排序

在大多数终端中,您还可以点击页脚中的“按总内存排序”、“按自用内存排序”和“按分配排序”按钮。

排序列的标题下有下划线。

查看不同的线程

默认情况下,live 命令将显示程序的主线程。您可以通过按大于号和小于号键(<>)查看程序的不同线程。在大多数终端中,您还可以点击页脚中的“上一个线程”和“下一个线程”按钮。

API

除了使用 memray run 从 CLI 跟踪 Python 进程外,还可以在运行的 Python 程序中编程启用跟踪。

import memray

with memray.Tracker("output_file.bin"):
    print("Allocations will be tracked until the with block ends")

有关详细信息,请参阅 API 文档

许可

Memray 采用 Apache-2.0 许可协议,如 LICENSE 文件中所示。

行为准则

此项目已采用行为准则。如果您对准则有任何疑问或在该项目中遇到的行为问题,请联系我们 opensource@bloomberg.net

安全策略

如果您认为您已在此项目中发现了一个安全漏洞,请将详细说明该疑似问题以及您找到的任何重现方法的电子邮件发送到项目团队邮箱 opensource@bloomberg.net

请勿在GitHub仓库中创建问题,因为我们希望将漏洞报告保持私密,直到我们有时间审查并处理这些问题。

贡献

我们欢迎您的贡献,以帮助我们改进和扩展此项目!

以下是一些基本步骤,您需要遵循才能为项目做出贡献。如果您对此过程或向彭博开源项目做出贡献的任何其他方面有任何疑问,请随时发送电子邮件至 opensource@bloomberg.net,我们将尽快解答您的问题。

贡献许可

由于此项目是根据开源许可条款分发的,因此您做出的贡献也受相同条款的许可。为了使我们能够接受您的贡献,我们需要您明确确认您有能力和意愿根据这些条款提供它们,我们用于此的机制称为开发者起源证书(DCO)。这与Linux内核、Samba和许多其他主要开源项目所使用的流程非常相似。

要参与这些条款,您必须做的只是将以下类似行作为您贡献中每个提交的提交信息中的最后一行。

Signed-Off-By: Random J. Developer <random@developer.example.org>

实现此目的的最简单方法是向您的 git commit 命令中添加 -s--signoff

您必须使用您的真实姓名(抱歉,不接受化名和匿名贡献)。

步骤

  • 创建一个问题,选择“功能请求”,并解释所提议的更改。
  • 遵循您所提供的 issue 模板中的指南。
  • 提交问题。
  • 提交一个拉取请求,并在拉取请求摘要中包含 "#" 以将其链接到问题。

项目详情


下载文件

下载适合您平台的应用文件。如果您不确定选择哪个,请了解有关 安装包 的更多信息。

源分发

memray-1.14.0.tar.gz (1.0 MB 查看哈希值)

上传时间

构建发行版

memray-1.14.0-cp313-cp313-musllinux_1_1_x86_64.whl (8.3 MB 查看哈希值)

上传时间 CPython 3.13 musllinux: musl 1.1+ x86-64

memray-1.14.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (8.4 MB 查看哈希值)

上传时间 CPython 3.13 manylinux: glibc 2.17+ x86-64

memray-1.14.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl (8.1 MB 查看哈希值)

上传时间 CPython 3.13 manylinux: glibc 2.17+ i686

memray-1.14.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (8.0 MB 查看哈希值)

上传时间 CPython 3.13 manylinux: glibc 2.17+ ARM64

memray-1.14.0-cp313-cp313-macosx_11_0_arm64.whl (893.8 kB 查看哈希值)

上传时间 CPython 3.13 macOS 11.0+ ARM64

memray-1.14.0-cp313-cp313-macosx_10_14_x86_64.whl (922.2 kB 查看哈希值)

上传时间 CPython 3.13 macOS 10.14+ x86-64

memray-1.14.0-cp312-cp312-musllinux_1_1_x86_64.whl (8.4 MB 查看哈希值)

上传时间 CPython 3.12 musllinux: musl 1.1+ x86-64

memray-1.14.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (8.4 MB 查看哈希值)

上传时间 CPython 3.12 manylinux: glibc 2.17+ x86-64

memray-1.14.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl (8.1 MB 查看哈希值)

上传时间 CPython 3.12 manylinux: glibc 2.17+ i686

memray-1.14.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (8.0 MB 查看哈希值)

上传时间 CPython 3.12 manylinux: glibc 2.17+ ARM64

memray-1.14.0-cp312-cp312-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (8.4 MB 查看哈希值)

上传时间: CPython 3.12 manylinux: glibc 2.12+ x86-64

memray-1.14.0-cp312-cp312-macosx_11_0_arm64.whl (898.4 kB 查看哈希值)

上传时间: CPython 3.12 macOS 11.0+ ARM64

memray-1.14.0-cp312-cp312-macosx_10_14_x86_64.whl (926.8 kB 查看哈希值)

上传时间: CPython 3.12 macOS 10.14+ x86-64

memray-1.14.0-cp311-cp311-musllinux_1_1_x86_64.whl (8.4 MB 查看哈希值)

上传时间: CPython 3.11 musllinux: musl 1.1+ x86-64

memray-1.14.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (8.4 MB 查看哈希值)

上传时间: CPython 3.11 manylinux: glibc 2.17+ x86-64

memray-1.14.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl (8.2 MB 查看哈希值)

上传时间: CPython 3.11 manylinux: glibc 2.17+ i686

memray-1.14.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (8.1 MB 查看哈希值)

上传时间: CPython 3.11 manylinux: glibc 2.17+ ARM64

memray-1.14.0-cp311-cp311-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (8.4 MB 查看哈希值)

上传时间: CPython 3.11 manylinux: glibc 2.12+ x86-64

memray-1.14.0-cp311-cp311-macosx_11_0_arm64.whl (900.9 kB 查看哈希值)

上传时间: CPython 3.11 macOS 11.0+ ARM64

memray-1.14.0-cp311-cp311-macosx_10_14_x86_64.whl (926.5 kB 查看哈希值)

上传于 CPython 3.11 macOS 10.14+ x86-64

memray-1.14.0-cp310-cp310-musllinux_1_1_x86_64.whl (8.3 MB 查看哈希)

上传于 CPython 3.10 musllinux: musl 1.1+ x86-64

memray-1.14.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (7.9 MB 查看哈希)

上传于 CPython 3.10 manylinux: glibc 2.17+ ARM64

memray-1.14.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (8.3 MB 查看哈希)

上传于 CPython 3.10 manylinux: glibc 2.12+ x86-64

memray-1.14.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl (8.3 MB 查看哈希)

上传于 CPython 3.10 manylinux: glibc 2.12+ i686

memray-1.14.0-cp310-cp310-macosx_11_0_arm64.whl (897.8 kB 查看哈希)

上传于 CPython 3.10 macOS 11.0+ ARM64

memray-1.14.0-cp310-cp310-macosx_10_14_x86_64.whl (922.5 kB 查看哈希)

上传于 CPython 3.10 macOS 10.14+ x86-64

memray-1.14.0-cp39-cp39-musllinux_1_1_x86_64.whl (8.3 MB 查看哈希)

上传于 CPython 3.9 musllinux: musl 1.1+ x86-64

memray-1.14.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (7.9 MB 查看哈希)

上传于 CPython 3.9 manylinux: glibc 2.17+ ARM64

memray-1.14.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (8.3 MB 查看哈希)

上传于 CPython 3.9 manylinux: glibc 2.12+ x86-64

memray-1.14.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl (8.3 MB 查看哈希)

上传于 CPython 3.9 manylinux: glibc 2.12+ i686

memray-1.14.0-cp39-cp39-macosx_11_0_arm64.whl (899.1 kB 查看哈希值)

上传于 CPython 3.9 macOS 11.0+ ARM64

memray-1.14.0-cp39-cp39-macosx_10_14_x86_64.whl (923.8 kB 查看哈希值)

上传于 CPython 3.9 macOS 10.14+ x86-64

memray-1.14.0-cp38-cp38-musllinux_1_1_x86_64.whl (8.4 MB 查看哈希值)

上传于 CPython 3.8 musllinux: musl 1.1+ x86-64

memray-1.14.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (8.0 MB 查看哈希值)

上传于 CPython 3.8 manylinux: glibc 2.17+ ARM64

memray-1.14.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (8.5 MB 查看哈希值)

上传于 CPython 3.8 manylinux: glibc 2.12+ x86-64

memray-1.14.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl (8.4 MB 查看哈希值)

上传于 CPython 3.8 manylinux: glibc 2.12+ i686

memray-1.14.0-cp38-cp38-macosx_11_0_arm64.whl (917.2 kB 查看哈希值)

上传于 CPython 3.8 macOS 11.0+ ARM64

memray-1.14.0-cp38-cp38-macosx_10_14_x86_64.whl (944.8 kB 查看哈希值)

上传于 CPython 3.8 macOS 10.14+ x86-64

memray-1.14.0-cp37-cp37m-musllinux_1_1_x86_64.whl (6.4 MB 查看哈希值)

上传于 CPython 3.7m musllinux: musl 1.1+ x86-64

memray-1.14.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (7.9 MB 查看哈希值)

上传于 CPython 3.7m manylinux: glibc 2.17+ ARM64

memray-1.14.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (6.4 MB 查看哈希值)

上传于 CPython 3.7m manylinux: glibc 2.12+ x86-64

memray-1.14.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl (6.4 MB 查看哈希值)

上传于 CPython 3.7m manylinux: glibc 2.12+ i686

由以下支持