为什么 sys.getsizeof() 报告两个实例的大小相同,即使其中一个实例具有额外的属性?


import sys
class MyObject:
def __init__(self,name,salary):
self.name = name
self.salary = salary
obj1 = MyObject("Tushar", 50)
obj2 = MyObject("Tushar", 50)
obj2.age = 20
print(sys.getsizeof(obj1))  # 56
print(sys.getsizeof(obj2))  # 56

为什么obj2具有额外的age属性时只有 56 个字节?

sys.getsizeof()仅为您提供直接引用的系统内存使用情况。实例对象不直接存储属性,默认情况下,这些属性存储在__dict__名称引用的字典对象中。字典也将键和值存储为引用,sys.getsizeof()只会为您提供字典内部 C 数组和其他内部簿记属性的内存大小,而不是键或值本身。

sys.getsizeof()文档中:

仅考虑直接归因于对象的内存消耗

,而不考虑它所引用的对象的内存消耗。

您必须递归收集对象大小,直到用完属性或键值对等。文档链接到此示例代码,向您展示如何执行此操作。

该特定配方不支持实例,但在这里传入对象的__dict__属性就足够了:

>>> total_size(obj1.__dict__)
303
>>> total_size(obj2.__dict__)
383

因此,这两个对象具有不同的总大小属性字典。

请注意,Python 缓存或实习对象的地方很多,因此不要将这些内存大小视为绝对值。例如,小整数被扣留,因此CPython内存中只有一个50整数对象,但在上面的total_size()输出中单独计数。

现代 CPython 版本还可以通过让这两个实例的__dict__字典对象共享键上的数据来节省内存,前提是给定类的绝大多数实例将具有相同的属性。

在分析sys.getsizeof()数据时要考虑到这一点。如果你想分析Python内存的使用,你最好先学习如何使用tracemalloc工具。

最新更新