Python中如何查找一个对象使用了多少内存

315

你想知道如何查找对象正在使用多少内存?我知道可以查找代码块使用了多少内存,但不知道如何查找实例化对象在其生命周期中的内存使用情况。


1
objgraph 看起来很有趣:http://mg.pov.lt/objgraph/ - user216430
相似:https://dev59.com/9HRB5IYBdhLWcg3w-789 - matt b
另一种方法是使用pickle。请参见此问题的重复项的此答案 - drevicko
图形化测试:https://dev59.com/E2Ag5IYBdhLWcg3w7uyk#30008338 - tmthydvnprt
1
如果它是你的类的对象,你可以向用户表现得很友好,并为他们实现__sizeof__(self)。例如NumPy就这样做了,而a.__sizeof__()a.nbytes(分配数组中的字节数)要大一些(包括对象开销)。 - Tomasz Gandor
5个回答

210

试试这个:

sys.getsizeof(object)

getsizeof()方法返回对象占用的字节数,它调用对象的__sizeof__方法并添加额外的垃圾回收开销(如果对象由垃圾回收器管理)

递归算法示例


14
sys.getsizeof(object)返回的值是否包括实际对象大小,而不是像fserb之前所说的指针大小? - Clock ZHONG
41
不,它将返回指针的大小。 - lstyls
9
这个和 object.__sizeof__() 有什么区别?似乎 sys.getsizeof(object) 返回的值稍微大一点。编辑:后者还包括垃圾回收器的开销。 - Mateen Ulhaq
1
我发现 sys.getsizeof(object.copy) 经常给出正确的值,而 sys.getsizeof(object) 给出的值要低得多(我猜是指针大小)。 - Andrew D. King
3
不正确。我在CPU上创建了一个PyTorch张量,其形状为(100000000,),sys.getsizeof(x.copy)显示为80。但数据类型是float64。 - GoingMyWay
显示剩余2条评论

158
找出Python对象的内存大小并不容易,因为Python对象(如列表和字典)可能会引用其他Python对象(在这种情况下,您的大小将包含每个对象的大小吗?还是不包括它们?)。同时,Python对象有一些指针开销和与对象类型和垃圾回收相关的内部结构。最后,一些Python对象具有非明显的行为。例如,列表为更多对象保留空间,大多数时间;字典更加复杂,因为它们可以以不同的方式运行(它们对于少量键有不同的实现,并且有时会超额分配条目)。
有一个大段代码(以及一个更新的大段代码)可以尝试最佳地近似 Python 对象在内存中的大小。
您还可以查看关于PyObject(表示几乎所有Python对象的内部C结构体)的一些旧描述

8
似乎现在Pympler模块中再次使用了“again”。 - FriendFX
2
如果你的对象非常简单,例如一个带有 Int -> (Int, Int) 映射的字典,理论上计算这样一个对象的大小应该很简单,对吧? - David Sanders
2
如果一本书引用了其他书籍,它的大小并不会增加。 - j riv

8
我没有使用过以下任何一种,但是简单搜索“Python [memory] profiler”会得到以下结果: 希望这能帮到你。

都是针对Python2的,不幸的是。 - Demetry Pascal

7

使用这个方法需要小心,因为对象的__sizeof__被覆盖可能会导致误导。

使用bregman.suite时,对sys.getsizeof的一些测试表明,在对象实例中将一个数组对象(data)复制后,它的大小比对象本身(mfcc)还要大。

>>> mfcc = MelFrequencyCepstrum(filepath, params)
>>> data = mfcc.X[:]
>>> sys.getsizeof(mfcc)
64
>>> sys.getsizeof(mfcc.X)
>>>80
>>> sys.getsizeof(data)
80
>>> mfcc
<bregman.features.MelFrequencyCepstrum object at 0x104ad3e90>

3

对于大型对象,您可以使用一种粗略但有效的方法:检查您的Python进程在系统中占用了多少内存,然后删除该对象并比较。

这种方法有许多缺点,但对于非常大的对象,它将为您提供一个非常快速的估计。


5
这可能不会产生实际效果。在进程中释放的内存并不一定需要归还给操作系统,因此寻找内存使用量的减少可能不太准确。 - nobody
15
在创建对象之前和之后测量Python进程的资源使用情况的类似方法将非常有效。 - Antony Hatchkins
8
@AntonyHatchkins,不要这么想,因为Python内存管理器并不一定从操作系统获取新的内存。在某种程度上,即使不使用,内存池也保持分配状态,因此当有新请求时,可以满足需求,无需从操作系统请求更多内存。 换句话说,这种方法对于对象的创建和销毁都是不可靠的。 - spider

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接