Python:内存泄漏?

时间:2012-12-14 16:08:43

标签: python performance optimization memory-leaks

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

您认为它现在消耗多少?

http://i.imm.io/P5Yq.png

str的大小为28,而上一个例子为12。因此,预期的内存使用量为267Mb - 甚至超过整数。但它只需要~40Mb!

2 个答案:

答案 0 :(得分:14)

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

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

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

答案 1 :(得分:2)

什么是getsizeof()

首先,我建议看一下运营商的规模意味着什么。您可以在documentation中找到确切的说明。我想放大下面的句子。

  

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

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