读取Python的输出memory_profiler

时间:2018-08-30 08:13:43

标签: python python-3.x memory-profiling

我在理解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()测量了此列表的大小。我仔细检查了它是否实际上是一个整数列表:

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 MiBmemory_profiler的输出显示MiB)。现在的问题是,表中有0.328125 MiB,所以差异为0.061096191 MB。

我在这里的担心是,在Python中构造列表是否真的需要大量内存,还是我以错误的方式解释了某些内容?

和PS:为什么当此a列表的长度为1000000时,在创建该行时,Increment列中该行的编号就像-9xxx MiB ?我的意思是为什么负数?

1 个答案:

答案 0 :(得分:6)

Python列表不存储对象本身,而是存储对象的引用。 Python的64位版本每个引用使用8个字节,因此10000个整数需要80000个字节。在您的示例中,sys.getsizeof(a)返回了87624,因为为了提高效率,列表分配了与其大小成比例的额外空间。 See this post for more

int占用的空间取决于它的大小,但是在int之前的2^30-1似乎在64位Python上占用了28个字节({{ 1}},仅占用24个字节)。因此,列表的大小总计为0字节,大约为87624 + 279996 = 367620

此与0.35 MiB的输出之间的差异可能是由于this

  

此模块通过查询操作获取内存消耗   有关当前进程具有的内存量的系统内核   已分配,可能与内存量略有不同   实际上是Python解释器使用的。另外,由于   垃圾收集器在Python中工作,结果可能会有所不同   在平台之间,甚至在运行之间。