程序执行过程中,如果RAM中有大量的对象在运行,就可能会出现内存问题,特别是在对可用内存总量有限的情况下。
下面是一些减少字典对象内存大小的方法,这些方法可以显著减少对象所需的RAM大小。
在Python里用字典来表示结构信息是非常方便的:
>>> ob ={'x':1,'y':2,'z':3}
>>> x = ob['x']
>>> ob['y']= y
但我们来看看它的内存消耗:
>>>print(sys.getsizeof(ob))
240
这个数额看起来好像挺小,但是当你想要创造许多这样的变量时就积少成多了:
对象数目 | 内存大小 |
---|---|
1 000 000 | 240 Mb |
10 000 000 | 2.40 Gb |
100 000 000 | 24 Gb |
用类实例来代替字典:
classPoint:
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
>>> ob =Point(1,2,3)
>>> x = ob.x
>>> ob.y = y
类实例各个部分的内存大小:
Field | Size (bytes) |
---|---|
PyGC_Head | 24 |
PyObject_HEAD | 16 |
weakref | 8 |
dict | 8 |
TOTAL: | 56 |
如果你不是很了解类和实例,可以看廖雪峰的这篇文章:
https://www.liaoxuefeng.com/wiki/1016959663602400/1017496031185408
这里的__weakref__是对这个对象的弱引用列表的引用,而__dict__是对类实例字典的引用,它包含实例属性的值。从Python 3.3开始, 类的所有实例用共享空间存储字典的keys. 这减少了内存中实例的大小:
>>>print(sys.getsizeof(ob), sys.getsizeof(ob.__dict__))
56 112
56+112=168 < 240. 因此,大量的类实例占用的内存比普通字典(dict)要少:
实例数目 | 大小 |
---|---|
1 000 000 | 168 Mb |
10 000 000 | 1.68 Gb |
100 000 000 | 16.8 Gb |
字典占实例大小的百分比为112/168=67%, 我们还是可以看出,实例中字典的大小严重影响了RAM中实例的大小。下面有更好的方法。
通过消除__dict__和weakref__,可以显著减少RAM中的类实例的大小。用__slots__是有可能做到的:
classPoint:
__slots__ ='x','y','z'
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
>>> ob =Point(1,2,3)
>>>print(sys.getsizeof(ob))
64
RAM中的对象明显变小:
Field | Size (bytes) |
---|---|
PyGC_Head | 24 |
PyObject_HEAD | 16 |
x | 8 |
y | 8 |
z | 8 |
TOTAL: | 64 |
今日重点:在类定义中使用__slots__会显著减少大量实例的内存占用
实例数目 | 大小 |
---|---|
1 000 000 | 64 Mb |
10 000 000 | 640 Mb |
100 000 000 | 6.4 Gb |
目前,这是大幅度减少RAM中类实例的内存占用的主要方法。相比于单纯用字典,减少了(240-64)/240= 73% 的内存占用。
全部0条评论
快来发表一下你的评论吧 !