PEP 683 改变了 Python 原有引用计数的一些逻辑,下面简单介绍一下。

CPython 的“引用计数可变性”已经成为并发、性能和未来发展的系统性障碍。


引用对象导致 “逻辑不可变对象” ≠ “物理不可变对象”

在 Cpython 中

  • None
  • True/False
  • int, str, list 等内建对象

在运行时引用计数会频繁变动,这意味着内存内容在不断被写入,在底层并非真正的 immutable


引用计数写操作降低并发性能

  • CPU Cache Line 失效

    Py_INCREF / Py_DECREF 会写内存 -> cache line invalidation

    在多线程 / 多核环境中,同一个全局对象被频繁引用,会造成严重的缓存抖动

  • fork + Copy-on-Write 失效

    父子进程共享内存页

    只要引用计数一变 -> 页面被写 -> 触发 COW

    只是“多拿了个引用”,却导致整页内存复制


为 free-threading (no GIL) 清扫道路

CPython 的引用计数本质是全局共享的可变状态,在无 GIL 下会产生高频数据竞争。 要么给 refcount 加锁(性能太差),要么让一部分的 refcount 不再变化。

该提案将“对象生命周期模型”划分成了两类对象

对象类型生命周期refcount 行为
普通对象动态正常增减
不朽对象解释器级固定,不参与 gc

这让后续优化和推理都更清晰,也会导致 sys.getrefcount() 不再具有语义价值,测试默认返回 2 的 23 次方减 1。