分析正在运行的 Python 进程的内存使用情况

问题描述 投票:0回答:2

我有一个 Python 进程,在很长一段时间(至少 10 小时,有时更长)后开始泄漏内存。这个问题很难重现,因此我想在问题出现时附加到正在运行的 Python 解释器,并以某种方式检查内存使用情况,例如通过获取当前分配最多内存的对象列表。

使用tracemallocmemory-profiler等常用分析工具很难做到这一点,因为它们需要成为代码的一部分或与进程一起启动,并且它们对运行时性能有重大影响。

我想要的是一个采样分析器,我可以简单地将其附加到现有的 Python 进程(如 py-spy),但 py-spy 只能让我了解函数中花费的 CPU 时间,而不是内存使用情况。

是否有其他工具或不同的方法可以帮助我深入了解现有 Python 进程的内存使用情况?

edit:我刚刚找到了pyrasite,它提供了pyrasite-memory-viewer命令,这正是我正在寻找的,但不幸的是该项目似乎已被放弃,我无法获取它可以在 Python 3.8 上运行。

python python-3.x memory-leaks profiling
2个回答
1
投票

https://github.com/vmware/chap(开源代码)可以满足您在此处的请求,只要您可以在 Linux 上运行您的应用程序。

  1. 等到您相信您对应用程序当时拥有的分配感兴趣为止。

  2. 为您的进程收集实时核心(例如使用 gcore),但请确保首先设置 coredump 过滤器,如下所示:

    echo 0x37 >/proc/

    你的Python程序的pid/coredump_filter

    gcore

    你的Python程序的pid

  3. 打开章节中生成的核心。

  4. 根据章节提示执行以下操作:

    重定向至

    描述使用过的

  5. 编辑生成的文件或使用选择的工具对其进行后处理。

生成的文件将包含当前使用的每个分配的条目。对于与 python 对象相对应的对象,它们通常会显示 python 类型,如下所示:

Anchored allocation at 7f5e7bf2a570 of size 40 This allocation matches pattern ContainerPythonObject. This has a PyGC_Head at the start so the real PyObject is at offset 0x18. This has reference count 1 and python type 0x7f5e824c08a0 (dict) Anchored allocation at 7f5e7bf2a5b0 of size 40 This allocation matches pattern SimplePythonObject. This has reference count 3 and python type 0x7f5e824cdfe0 (str) This has a string of length 12 containing "ETOOMANYREFS".
您可以使用章节中的其他命令来理解为什么您感兴趣的任何分配都被锚定,基本上是因为它们允许您通过传入引用向后遍历,但是上面的命令应该足以让您弄清楚哪些类型的分配有高计数。

例如,假设您想了解如何引用 0x7f5e7bf2a570 分配中的字典。你可以执行这个命令:

chap> describe incoming 7f5e7bf2a570 /skipUnfavoredReferences true Anchored allocation at 17fda90 of size 1a8 This allocation matches pattern PyDictKeysObject. 1 allocations use 0x1a8 (424) bytes.
您可以反过来问 PyDictKeysObject 的引用是什么(不是 python 类型,但用于存储字典的键)

chap> describe incoming 17fda90 /skipUnfavoredReferences true Anchored allocation at 7f5e7c0e01f0 of size 40 This allocation matches pattern ContainerPythonObject. The garbage collector considers this allocation to be reachable. This has a PyGC_Head at the start so the real PyObject is at offset 0x18. This has reference count 1 and python type 0x7f5e824c08a0 (dict) 1 allocations use 0x40 (64) bytes.
    

0
投票
我相信

memray attach 选项就是您可能正在寻找的。 确保在将 memray

 附加到进程之前安装了 lldb 或 gdb。

© www.soinside.com 2019 - 2024. All rights reserved.