类与对象深度问题与解决技巧(2 如何为创建大量实例节省内存)

实际问题:
在游戏中,定义了玩家类player,每有一个在线玩家,在服务器内则有一个player的实例,当在线人数很多时,将产生大量实例(百万级)
如何降低这些大量实例的内存开销?

解决方案:
定义类的__slots__属性,声明实例有哪些属性(关闭动态绑定)
创建两个类,区别为Player2有slots方法

import sys
import tracemalloc

class Player1(object):
    def __init__(self, uname, uid, level=1):
        self.uname = uname
        self.uid = uid
        self.level = level


class Player2(object):
    __slots__=('uname', 'uid', 'level')
    def __init__(self, uname, uid, level=1):
        self.uname = uname
        self.uid = uid
        self.level = level

p1 = Player1('juran1', '001')
p2 = Player2('juran2', '002')

# 查找p1,p2中的属性
print(dir(p1))
print(dir(p2))

print(set(dir(p1)) - set(dir(p2)))
# {'__dict__', '__weakref__'}

wearef 弱引用
dict 动态绑定属性(主要的内存浪费)

p1.x = 'juran11'
print(p1.__dict__)
# {'uname': 'juran1', 'uid': '001', 'level': 1, 'x': 'juran11'}
# 所以可通过字典形式添加
p1.__dict__['y'] = 'juran111'
print(p1.__dict__)
# {'uname': 'juran1', 'uid': '001', 'level': 1, 'y': 'juran111'}

可是对Player2添加了__slot2__ 后对添加属性就会报错

p2.x = 'juran22'
# AttributeError: 'Player2' object has no attribute 'x'

所以slot方法限制了dict动态绑定属性

下面通过对内存的分析来反映Player1 和 Player2
1 首先调用sys库中的getsizeof方法分析(说明一下这种方法只能分析出字符串,列表等确定的内存大小)

print(sys.getsizeof(p1.__dict__))
print(sys.getsizeof(p1.uname))
print(sys.getsizeof(p1.uid))
# 112
# 55
# 52

说明主演占据内存的还是dict动态绑定属性

2 调用tracemalloc库进行分析

tracemalloc.start()
p1 = [Player1(1, 2, 3) for _ in range(100000)]      # 16.8 MiB
p2 = [Player2(1, 2, 3) for _ in range(100000)]        # 7837 KiB
end = tracemalloc.take_snapshot()

# 直接对文件大小变化进行统计
top = end.statistics('filename')
for stat in top[:10]:
    print(stat)

显而易见,没有dict动态绑定属性的占据更少的内存空间

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值