我想计算一个对象使用的内存。sys.getsizeof
很好,但它是浅层次的(例如,如果应用于列表,则不包括列表元素占用的内存)。
我想编写一个通用的“深层次”版本的sys.getsizeof
。我理解“深层次”一词的定义有些模糊;我完全满意 copy.deepcopy
所遵循的定义。
这是我的第一次尝试:
def get_deep_sizeof(x, level=0, processed=None):
if processed is None:
# we're here only if this function is called by client code, not recursively
processed = set()
processed.add(id(x))
mem = sys.getsizeof(x)
if isinstance(x, collections.Iterable) and not isinstance(x, str):
for xx in x:
if id(xx) in processed:
continue
mem += get_deep_sizeof(xx, level+1, processed)
if isinstance(x, dict):
mem += get_deep_sizeof(x[xx], level+1, processed)
return mem
它有两个已知问题和未知数量的未知问题:
- 我不知道如何以捕获所有链接对象的方式遍历通用容器。因此,我使用了
in
进行迭代,并硬编码字典的情况(以包括值,而不仅仅是键)。显然,这对于像字典之类的其他类是无效的。 - 我不得不硬编码排除
str
(它是可迭代的,但没有链接到任何其他对象)。同样,如果有更多类似的对象,则会出现问题。
我怀疑使用in
不是一个好主意,但我不确定还能做什么。