Python3中sys.getrefcount()返回值远高于预期的2是什么原因?
sys.getrefcount(1)返回148而非2的原因
- 你预期得到2的逻辑是成立的:对于普通自定义对象,
sys.getrefcount()的返回值会比对象的实际外部引用数多1,因为调用该方法时会临时为传入的对象新增一个引用,如果对象只有一个变量指向它,返回值确实为2。 - 该结果和你正在学习的GIL没有直接关联,核心原因是CPython的小整数缓存优化机制:
- 为了避免频繁创建销毁小整数带来的性能开销,CPython默认会提前创建好
[-5, 256]范围内的所有整数对象,放在全局小整数池中缓存,整个解释器运行过程中,所有用到该数值的场景都会直接复用同一个缓存对象,不会生成新的实例。 - 你测试用的数值1属于小整数缓存范围,解释器启动后,内部的内置模块、运行逻辑已经大量用到了数值1,累计下来就有148个引用指向这个全局缓存的1对象,
sys.getrefcount()统计的是该对象的全进程总引用数,自然远大于2。
- 为了避免频繁创建销毁小整数带来的性能开销,CPython默认会提前创建好
- 你可以使用超出小整数缓存范围的数值测试,就能得到符合预期的结果:
import sys c = 1024 print(sys.getrefcount(c)) # 输出为2,和你的预期一致
- 除了小整数外,CPython对短字符串也有类似的intern缓存机制,测试这类对象时也会出现引用计数远大于预期的情况。
- 注:以上是CPython解释器的实现特性,其他Python解释器(如PyPy)的行为可能存在差异。
内容的提问来源于stack exchange,提问作者Rohit Agharkar
相关产品推荐
相关产品推荐

