https://github.com/vmware/chap(开源代码)可以实现您在此请求的功能,只要您能在Linux上运行应用程序。
等待直到您认为此时应用程序具有的分配情况很有趣。
为您的进程收集一个活动核心(例如使用gcore),但首先确保设置了核心转储过滤器,如下所示:
echo 0x37 >/proc/pid-of-your-python-program/coredump_filter
gcore pid-of-your-python-program
在chap中打开生成的核心文件。
从chap提示符处执行以下操作:
redirect on
describe used
编辑生成的文件或使用所选工具进行后处理。
生成的文件将对当前正在使用的每个分配条目进行记录。 对于与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中还有其他命令可用于理解你感兴趣的任何分配是如何锚定的,基本上是因为它们允许您通过传入引用向后遍历,但以上内容足以使您能够弄清具有高计数的哪些类型的分配。
例如,假设您想了解在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.