为何删除变量并触发GC后仍可通过ID访问Python对象?
问题原因解析
小整数缓存机制:Python为优化性能,会预先创建并缓存范围在*-5到256*之间的整数对象。这些对象在进程启动时就加载到内存,全局共享,不会被垃圾回收机制回收。你创建
x = 10时,只是让变量x指向缓存池里的10对象;删除x后,该对象仍在缓存池中,调用gc.collect()也不会销毁它。ctypes直接访问内存地址:
id()返回的是对象的内存地址,当你用ctypes通过该地址访问时,因为10的对象还在内存中,所以能正常读取到它。验证方式:测试非小整数:如果换成超出小整数池范围的数值(比如257),重复操作后再用
ctypes访问,就会出现错误或无效内容——因为这类整数不在缓存池里,删除变量并触发垃圾回收后,对应的内存会被回收。
示例代码:
import gc import ctypes # 小整数测试 x = 10 x_id = id(x) del x gc.collect() obj = ctypes.cast(x_id, ctypes.py_object).value print(obj) # 输出10 # 非小整数测试 y = 257 y_id = id(y) del y gc.collect() try: obj = ctypes.cast(y_id, ctypes.py_object).value print(obj) except Exception as e: print(f"访问失败: {e}") # 大概率报错
内容的提问来源于stack exchange,提问作者orel_gzl
相关产品推荐
相关产品推荐

