10

在 Python 解释器中查询:

Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> k = [i for i in xrange(9999999)]
>>> import sys
>>> sys.getsizeof(k)/1024/1024
38
>>>

在这里 - 看看它需要多少 RAM:


语句后的内存使用del k

之后gc.collect()

为什么预期大小为 38Mb 的整数列表需要 160Mb?

UPD: 这部分问题得到了回答(几乎立即和多次:))

好的 - 这是另一个谜语:

Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys

>>> str = 'abcdefg'
>>> sys.getsizeof(str)
28
>>> k = []
>>> for i in xrange(9999999):
...     k.append(str)
...
>>> sys.getsizeof(str)*9999999/1024/1024
267

你认为它现在会消耗多少?


(来源:i.imm.io

大小str为 28,而在过去的示例中为 12。因此,预期的内存使用量为 267Mb - 甚至比整数还要多。但它只需要~40Mb!

4

2 回答 2

14

sys.getsizeof()不是很有用,因为它通常只占您期望的一部分。在这种情况下,它考虑了列表,但不是列表中的所有整数对象。该列表每项大约占用 4 个字节。整数对象每个占用另外 12 个字节。例如,如果您尝试这样做:

k = [42] * 9999999
print sys.getsizeof(k)

您会看到该列表仍为每个项目占用 4 个字节,即大约 40MB,但因为所有项目都是指向同一个整数对象 42 的指针,所以总内存使用量不会超过 40MB。

于 2012-12-14T16:19:45.410 回答
2

什么是 getsizeof()

首先,我建议看一下 size-of 运算符的含义。您可以在文档中找到确切的描述。我想放大以下句子。

只考虑直接归因于对象的内存消耗,而不考虑它所引用的对象的内存消耗。

这意味着当您询问 sys.getsizeof([a]) 时,您不会得到数组的实际大小。您只能获得专用于管理列表的所有内存的大小。该列表仍然包含 9999999 个整数。每个整数由 12 个字节组成,总共 114 MB。专用于管理数组的内存总和 32MB 加上数组中数据的内存总和为 146 Mb,这更接近您的结果。

于 2012-12-14T16:37:51.207 回答