← [ BACK_TO_NOTES ]

Python 对象模型与内存

一切皆对象:对象有身份类型值;CPython 以引用计数为主回收,辅以循环 GC。

#concept #growing #dev #python #python

[!info] related notes

Python 对象模型与内存

这个概念为什么出现

id、共享、循环引用、__slots__ 内存——都依赖“对象头 + 引用”这一层。本篇给 CPython 直觉,并标明实现边界。

[!abstract] 一句话理解 名字绑定对象,对象有身份、类型和值;CPython 使用引用计数并辅以循环 GC。具体回收时机和内存布局不是 Python 语言保证。

最小可观察示例

场景:观察对象身份与引用变化

# object_identity_demo.py
# 业务意图:展示同一 list 多引用与 is。
# 教学点:对象身份;引用共享。

def main() -> None:
    a = ["order"]
    b = a
    print("id equal?", id(a) == id(b), "is?", a is b)
    b.append("line")
    print(a)


if __name__ == "__main__":
    main()

建议运行:

python object_identity_demo.py

期望输出:

id equal? True is? True
['order', 'line']

结合场景再看三个关注点

  1. 身份稳定于对象生命周期。
  2. 共享写可见。
  3. 引用计数细节用工具观察,不靠猜。

核心概念与准确模型

  • 每个对象:身份、类型、值
  • CPython:PyObject 头含引用计数等
  • 分配器随构建而异(例如 pymalloc、free-threaded 构建中的 mimalloc);对象回收不等于内存立即归还操作系统。
  • slots 可避免为实例自动创建 dict;若基类已有 dict,或显式声明 dict,实例仍可有字典。

边界情况与反直觉行为

  1. intern 使某些字面量身份重合
  2. 循环引用 单靠计数不够
  3. free-threaded 引用计数可能延迟释放;immortal 对象也不按普通对象的引用计数回收。不要靠 del 保证文件或锁及时释放,应使用上下文管理器。

常见误区

[!warning] 常见误区:id 当序列号持久化 错误理解:id 全局永久唯一可存库。
正确模型:只在进程内生命周期有意义。

工程实践

  • 大对象及时释放引用
  • tracemalloc 观察被跟踪的 Python 分配;不能据此推断所有原生库分配或进程 RSS。
  • 热路径对象池要非常谨慎

本节总结

对象模型连接语言使用与运行时成本。下一篇专讲 GC 与循环。

自测题

  1. 名字删除是否立即释放对象?
  2. 为什么 id 不适合持久化?
参考答案
  1. del 只删除绑定;其他引用仍可保留对象。常规 CPython 引用计数归零通常触发回收,但不能将此作为跨实现、跨构建的资源释放契约。
  2. 可复用且仅进程内有效。

延伸阅读与资料来源

资料类型支撑内容
Data model规范对象
gc module文档回收接口
Free-threaded Python文档回收延迟与分配器差异
创建于 2026/7/15 更新于 2026/10/6
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本