什么是non-heap type?如何判断Python对象是否为non-heap类型?
non-heap type相关问题解答
什么是non-heap type
这是CPython实现层面的概念,特指解释器底层静态定义、不存储在Python堆内存上的类型对象:
- 这类类型在解释器启动时就完成初始化,生命周期和整个进程绑定,不需要Python的垃圾回收机制负责分配和销毁
- 为了节省开销,这类类型默认不会实现GC要求的
traverse、clear等回调方法,内存分析工具如果尝试调用这类方法遍历该类型的引用,就会触发你遇到的崩溃 - 报错里的
gi._gi.GObject、Python内置的int、str、list的类型本身,都属于典型的non-heap type
判断non-heap类型的方法
首先注意:这个概念仅针对类型对象(也就是class本身),不适用于类的实例。你可以通过读取类型对象的__flags__属性的特定位来判断:
CPython中标记堆类型的位是Py_TPFLAGS_HEAPTYPE,对应值为1 << 9,Python层面判断代码如下:
Py_TPFLAGS_HEAPTYPE = 1 << 9 def is_non_heap_type(cls: type) -> bool: # 返回True说明是non-heap类型,返回False是堆类型 return not bool(cls.__flags__ & Py_TPFLAGS_HEAPTYPE)
测试示例:
is_non_heap_type(int)输出True,内置int类型是非堆类型is_non_heap_type(type("MyClass", (), {}))输出False,运行时动态创建的类是堆类型
当前报错的修复方案
meliae的扫描逻辑没有兼容非堆类型的处理,你可以修改/usr/local/lib/python3.6/site-packages/meliae/scanner.py的代码,在遍历对象引用前先判断当前类型是否为非堆类型,跳过对非堆类型的遍历即可,这类类型本身不会产生内存泄漏,不需要纳入分析范围。
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

