You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

函数局部变量未被GC清理,两次调用id相同的原因及解决方法

两次调用函数f()时变量a的id相同的原因及相关问题解答

原因:CPython的字符串驻留优化

你遇到的现象确实是CPython的**字符串驻留(String Interning)**优化导致的:

  • 代码中"wat wat wat wat wat wat wat wat"是编译阶段就能确定的字符串字面量,CPython会在编译时将这类字符串存入全局的字符串常量池,后续每次用到该字面量时,都会直接复用池中的同一个对象,而非重新创建新对象。
  • 函数f()每次调用时,变量a只是引用了常量池里的已有对象,因此两次输出的id完全一致。
  • 垃圾回收器不会回收这个对象,因为它被常量池的全局引用持有,属于可达对象,所以gc.collect()和等待时间都无法改变这个结果。

能否强制清理该对象?

很难通过常规手段强制清理:

  • 字符串常量池的引用由CPython内部维护,Python没有提供公开API来手动移除其中的对象。
  • 若想避免对象复用,可以将字符串改为动态生成(而非直接使用字面量),比如把a = "wat wat wat wat wat wat wat wat"改成a = "wat " * 8,这样每次调用函数时都会生成新的字符串对象,两次输出的id就会不同。

测试代码

import time

def f():
    a = "wat wat wat wat wat wat wat wat"
    print(id(a))

f()

for i in range(30):
    time.sleep(1)
    s = "/" if i % 2 == 0 else "\\"
    print(s, end="", flush=True)

print()
f()
# Tested with python 3.10.8
# 140443262854256
# ///////////////\
# 140443262854256

内容的提问来源于stack exchange,提问作者Alpensin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 19:36:12