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

q3qa4bjr  于 2023-10-21  发布在  Python
关注(0)|答案(2)|浏览(109)

我有一个Python进程,在很长一段时间后(至少10个小时,有时更长)开始泄漏内存。这个问题很难重现,因此我想在问题出现时附加到运行的Python解释器上,并以某种方式检查内存使用情况,例如。获取当前分配最多内存的对象列表。
这对于像tracemallocmemory-profiler这样的常用分析工具来说是很困难的,因为它们需要成为代码的一部分或与进程一起启动,并且它们对运行时性能有很大的影响。
我想要的是一个采样分析器,我可以简单地将其附加到现有的Python进程(如py-spy),但py-spy只能让我了解函数所花费的CPU时间,而不是内存使用情况。
是否有其他工具或不同的方法可以帮助我深入了解现有Python进程的内存使用情况?

  • edit*:我刚刚找到了pyrasite,它提供了pyrasite-memory-viewer命令,这正是我要找的,但不幸的是,这个项目似乎被放弃了,我无法让它在Python 3.8上工作。
qojgxg4l

qojgxg4l1#

https://github.com/vmware/chap(开放源代码)可以满足您的要求,只要您可以在Linux上运行您的应用程序。
1.等到您相信您对应用程序在该时间点的分配感兴趣时再进行操作。
1.为你的进程收集一个活的核心(例如使用gcore),但要确保先设置coredump过滤器,如下所示:
echo 0x37 >/proc/pid-of-your-python-program/coredump_filter
gcore pid-of-your-python-program
1.打开第一章中生成的核心。
1.在chap提示符下执行以下操作:
时重定向
描述使用
1.编辑生成的文件或使用所选工具对其进行后处理。
生成的文件将包含当前使用的每个分配的条目。对于对应于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".

你可以使用chap中的其他命令来理解为什么你感兴趣的任何分配都被锚定,基本上是因为它们允许你通过传入的引用向后遍历,但是上面的命令应该足以让你弄清楚哪些类型的分配具有高计数。
例如,假设您想了解如何引用位于0x 7 f5 e7 bf 2a 570的分配中的dict。你可以执行这个命令:

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.
wwtsj6pe

wwtsj6pe2#

我相信memrayattach选项是你可能正在寻找的。确保在将memray附加到进程之前安装lldb或gdb。

相关问题