为什么python似乎比sys.getsizeof帐户分配更多的内存?

为什么python似乎比sys.getsizeof帐户分配更多的内存?,python,Python,例如: import sys class Test(): def __init__(self): self.a = 'a' self.b = 'b' self.c = 'c' self.d = 'd' self.e = 'e' if __name__ == '__main__': test = [Test() for i in range(100000)] print(sys.getsiz

例如:

import sys

class Test():
    def __init__(self):
        self.a = 'a'
        self.b = 'b'
        self.c = 'c'
        self.d = 'd'
        self.e = 'e'

if __name__ == '__main__':
    test = [Test() for i in range(100000)]
    print(sys.getsizeof(test))
在windows任务管理器中:当创建一个10万对10万的列表时,我得到了大约20 MB的跳跃

使用sys.getsizeoff():对于100000的列表,我得到412236字节;对于10的列表,我得到100个字节


这似乎极不相称。为什么会发生这种情况?

分配的内存不是不成比例的;您正在创建100000个对象!如您所见,它们大约占用34 MB的空间:

>>> sys.getsizeof(Test())+sys.getsizeof(Test().__dict__)
344
>>> (sys.getsizeof(Test())+sys.getsizeof(Test().__dict__)) * 1000000 / 10**6
34.4 #megabytes
您可以使用
\uuuuu插槽\uuuuuu
获得一点改进,但仍需要大约20MB的内存来存储这100000个对象

>>> sys.getsizeof(Test2())+sys.getsizeof(Test2().__slots__)
200
>>> sys.getsizeof(Test2())+sys.getsizeof(Test2().__slots__) * 1000000 / 10**6
20.0 #megabytes
(请注意,
sys.getsizeof
不考虑引用。您可以自动完成以查看对象的大多数属性。)

见答案:

要使用
\uuuuuu插槽

class Test2():
    __slots__ = ['a','b','c','d','e']

    def __init__(self):
        ...

每个实例都引用一个dict,因为它的
\uuuu dict\uuuu
在我的机器上是272字节。将其乘以100000。

您可以使用迭代器(
xrange
在本例中)将内存20MB保存为什么度量?专用字节?虚拟大小?@Daniel DiPaolo:Windows任务管理器将其定义为:内存(专用工作虚拟集)。(它比我的internet explorer现在使用的还多!)
sys.getsizeof
返回一个浅值:它不包括列表中包含的对象。@DanielDiPaolo:如果您不确定,请阅读文档。大小包括列表本身(包含指针)分配的内存,但不包括指向的对象。这与插槽无关,它与分配对象时Python解释器的内存使用有关。插槽是减少这种使用的一种方法,但他在这里没有使用它们。@ninjagecko:我尝试将
\uuuu Slots\uuuuu
行代码添加到类定义中,但在内存使用方面似乎没有什么不同。(Py 2.7)@Jeff:你是用与测量“20MB”相同的东西,还是用
sys.getsizeof
?@ninjagecko:就sys.getsizeof而言,我是正确的。但任务管理器表示,它并没有解决占用多少内存的问题(不管有没有
\uuuuuu插槽
),杰夫:这里没有什么奇怪的事情:这是数学问题。100000个对象总共占用大约20兆字节的空间。见曼西的答案或修订后的答案。(Daniel DiPaolo不正确。)您应该将答案的标题编辑为“sys.getsizeof确实充分考虑了大多数对象”;分配的内存不是不成比例的。