直接测实例内存占用最有效,需控制变量:用sys.getsizeof()初筛同类实例自身开销(不含引用对象),tracemalloc定位分配源头,objgraph分析引用关系,并通过__slots__有无设计三组对照验证内存差异。

直接测实例内存占用是最有效的方式,关键在于控制变量、排除干扰、对比差异。
用 sys.getsizeof() 快速初筛
这个函数能返回对象本身占用的字节大小(不含引用对象),适合快速比较同类实例的底层开销:
- 确保所有测试类都使用相同初始化参数,避免数据内容影响结果
- 对每个类创建多个实例(如 1000 个),取平均值更稳定
- 注意:它不统计
__dict__里引用的大对象,只看实例结构本身
用 tracemalloc 定位内存分配源头
当需要知道“哪一行代码导致了额外内存”时,tracemalloc 比单纯看大小更有价值:
- 在测试前调用
tracemalloc.start() - 批量创建对象后,用
tracemalloc.get_traced_memory()获取增量 - 用
tracemalloc.take_snapshot()对比不同继承类的分配堆栈 - 特别关注是否出现
__dict__或__weakref__的大量分配——这是__slots__失效的典型信号
用 objgraph 查看实例引用关系
当怀疑子类意外持有了父类未声明的属性或闭包时,可视化引用链很直观:
-
objgraph.show_most_common_types(limit=20)查看高频类型 -
objgraph.show_growth()观察测试前后哪些类型数量激增 -
objgraph.show_backrefs([obj], max_depth=3)看某个实例被谁持有,确认是否因 getter 或 mock 导致长生命周期引用
真实场景下的对照组设计
别只测单个类,要构建可比组合:
- 对照组 A:父类有
__slots__,子类也有 → 应无__dict__ - 对照组 B:父类有
__slots__,子类无 → 必有__dict__,内存明显上升 - 对照组 C:父类无
__slots__,子类也无 → 默认行为,作为基准线 - 运行时统一禁用 GC(
gc.disable()),避免回收干扰测量











