python内存优化关键在于减少小对象数量、控制生命周期及选用省内存结构:用__slots__禁用__dict__、生成器替代全量加载、tuple/str替代list/bytes、weakref清理引用。

Python内存占用高,往往不是因为单个大对象,而是大量小对象长期驻留、引用关系复杂或数据结构选择不当。优化关键在于减少对象数量、控制生命周期、选用更省内存的数据结构。
用 __slots__ 限制实例属性,节省对象头开销
默认情况下,Python 为每个实例动态创建 __dict__ 字典来存储属性,带来显著内存开销(约 200–300 字节/实例)。对大量实例的类(如 ORM 模型、配置项、缓存条目),启用 __slots__ 可彻底禁用 __dict__,改用固定偏移量访问属性。
- 只声明需要的属性名,不支持动态赋值新属性(如
obj.new_attr = 1会报错) - 若需兼容字典访问,可手动实现
__getattr__或提供as_dict()方法 - 继承时子类也需定义
__slots__,否则父类的__slots__不生效
优先使用生成器和迭代器,避免一次性加载全量数据
用 list 存储百万级字符串或数值,内存峰值极易飙升;而生成器(yield)、itertools 工具或带 chunksize 的读取方式,让数据“按需生产”,常将内存从 GB 级压到 MB 级。
- 读文件时不用
lines = f.readlines(),改用for line in f: - 处理数据库结果集时,用
cursor.fetchmany(size)分批获取,而非fetchall() - 自定义逻辑中,把返回
list的函数改为yield生成器(如def parse_logs(): yield {...})
替换低效容器:tuple 代替 list,str 代替 bytes(当适用)
不可变对象在 Python 中有更紧凑的内存布局。若数据不需修改,用 tuple 替代 list 可减少约 10–15% 内存;同理,str 在 CPython 中对 ASCII 字符采用紧凑编码(compact ascii),比等长 bytes 更省空间(尤其含大量纯英文文本时)。
立即学习“Python免费学习笔记(深入)”;
- 配置项、枚举值、路径拼接结果等静态数据,优先定义为
tuple或NamedTuple - 日志消息、HTTP 响应头、JSON 键名等文本内容,确认无二进制需求时保持为
str - 注意:
bytes在处理网络流、加密、图像原始数据时不可替代,勿盲目替换
及时清理引用,主动触发垃圾回收(gc)
循环引用(如父子对象互相持有)或全局缓存未清理,会导致对象无法被及时回收。虽然 CPython 有引用计数+分代 GC,但某些场景下仍需干预。
- 用
weakref构建缓存(如WeakValueDictionary),避免强引用阻止销毁 - 显式删除大对象引用:
del large_data+gc.collect()(尤其在长生命周期函数末尾或内存敏感分支) - 用
objgraph或tracemalloc定位“存活却不再使用”的对象类型与引用链
不复杂但容易忽略。真正起效的优化,往往藏在类设计、数据流拆分和引用管理这些基础环节里。










