我在理解memory_profiler
的输出时遇到了问题。基本上,它看起来像这样:
Filename: tspviz.py
Line # Mem usage Increment Line Contents
================================================
7 34.589844 MiB 34.589844 MiB @profile(precision=6)
8 def parse_arguments():
9 34.917969 MiB 0.328125 MiB a = [x**2 for x in range(10000)]
在第9行,我们可以清楚地看到,我们使用了一些内存。现在,我使用
sys.getsizeof()
测量了此列表的大小。我仔细检查了它是否实际上是一个int列表:print(sys.getsizeof(a))
print(type(a[0]))
这就是我得到的:
87624
<class 'int'>
好吧,现在有一个问题。正如我所检查的那样,在我的64位Windows计算机上,Python中的int大小为
28
。我不知道那是不是正确的。但即便如此。 10000 * 28
= 0.28 MB。和0.28 MB = 0.267028809 MiB
(memory_profiler
的输出显示MiB)。现在的问题是,表中存在0.328125 MiB
,所以区别是0.061096191
MB。我的担心是,在Python中构造列表是否真的需要大量内存,还是我以错误的方式解释了某些内容?
P.S:为什么,当这个
a
列表的长度为1000000
时,当我创建该行时,该行的Increment
列中的数字就像-9xxx MiB?我的意思是为什么负数? 最佳答案
Python列表不存储对象本身,而是存储对象的引用。 Python的64位版本每个引用使用8个字节,因此10000
ints需要80000
字节。在您的示例中,sys.getsizeof(a)
返回87624
,因为为了提高效率,列表分配了与其大小成比例的额外空间。 See this post for more。int
占用的空间取决于它的大小,但是在64位Python上,int
直到2^30-1
似乎确实占用了28个字节(0
除外,后者仅占用24个字节)。因此,列表的总大小为87624 + 279996 = 367620
字节,大约为0.35 MiB
。
此与memory_profiler
的输出之间的差异可能是由于this造成的: