1. 创建大量实例节省内存
场景:在游戏中,定义了玩家类player,每有一个在线玩家,在服务器内则有一个player的实例,当在线人数很多时,将产生大量实例(百万级),如何节省内存?
先看下面代码:
class Player(object):
def __init__(self,uid,name,status=0,lever=0):
'''有默认值在实例化时不用传,但是在赋值时还是要写的'''
self.uid = uid
self.name = name
self.status = status
self.lever = lever
class Player2(object):
__slots__ = ['uid','name','status','lever'] #关闭动态绑定属性,在python 中 属性都是通过__dict__进行维护的,动态属性会占用内存,此处关闭动态绑定后,我们不能再通过 类.属性的这种方式新增属性
def __init__(self,uid,name,status=0,lever=0):
'''有默认值在实例化时不用传,但是在赋值时还是要写的'''
self.uid = uid
self.name = name
self.status = status
self.lever = lever
p1 = Player(1,'zjk')
p2 = Player2(2,'zs')
上面代码中,在player2这个类中我们增加了 __slots__魔法方法,此方法的作用是:关闭动态绑定属性,在python 中 属性都是通过__dict__进行维护的,动态属性会占用内存,此处关闭动态绑定后,并且限定了只有列表中的几个属性,也可以 用元组传递属性,我们不能再通过 类.属性的这种方式新增属性。会节省内存。
查看上面2个类中所差的属性有哪些
代码如下:
print(set(dir(p1))-set(dir(p2))) #为什么要转为集合,因为list列表,是不能进行差集运算的,也就是 - 操作
执行结果:
{’_weakref_’, ‘_dict_’}
我们可以看出,当我们设置slots后,这个类里的 上面的2个属性就没了,一个是_weakref_ 弱引用,一个是类中的动态绑定属性
查看类占用的内存空间大小 sys.getsizeof()
import sys
print(sys.getsizeof(p1.__dict__))
print(sys.getsizeof(p2.uid))
print(sys.getsizeof(p2.name))
执行结果:
112
28
51
我们看出,没有关闭动态属性的时候,内存要大
2. 跟踪内存
将上面的代码我们进行改造,引入内存跟踪的类,并且将2个类分别实例化100000次,并打印相应的内存大小
import sys
class Player(object):
def __init__(self,uid,name,status=0,lever=0):
'''有默认值在实例化时不用传,但是在赋值时还是要写的'''
self.uid = uid
self.name = name
self.status = status
self.lever = lever
class Player2(object):
__slots__ = ['uid','name','status','lever'] #关闭动态绑定属性,在python 中 属性都是通过__dict__进行维护的,动态属性会占用内存,此处关闭动态绑定后,我们不能再通过 类.属性的这种方式新增属性
def __init__(self,uid,name,status=0,lever=0):
'''有默认值在实例化时不用传,但是在赋值时还是要写的'''
self.uid = uid
self.name = name
self.status = status
se