如何对Python模块级变量执行垃圾回收以释放模块加载后的冗余内存?
Python模块加载大文件避免内存残留的方案说明
最优方案:将计算逻辑封装到函数内部
这是最推荐的实现方式,无需手动管理内存,兼容所有Python版本,代码可维护性更高。
原写法的问题在于data是模块级全局变量,只要模块保持加载状态,模块对象就会一直持有data的引用,垃圾回收器永远不会回收这部分内存。
封装后的代码示例如下:
# getstuff.py 优化后代码 from importlib_resources import files def _compute_target(): # data为函数局部变量,函数执行结束后引用计数自动归零 data = files('path.to.file').joinpath('big.one').read_text() return some_complicated_operation(data) stuff_i_care_about = _compute_target() # 可选操作:删除临时函数,避免对外暴露内部实现 del _compute_target
# __init__.py 无需修改 from .getstuff import stuff_i_care_about
函数执行完成后,局部变量data没有任何外部引用,CPython的引用计数机制会立刻释放这部分内存,不需要额外手动操作。
替代方案:手动删除模块级变量
如果不想调整代码结构,也可以在生成目标数据后直接删除data变量:
# getstuff.py 手动删除版本 from importlib_resources import files data = files('path.to.file').joinpath('big.one').read_text() stuff_i_care_about = some_complicated_operation(data) # 手动删除模块级的data变量,移除引用 del data
这种场景下不需要主动调用gc.collect():data是普通字符串对象,不存在循环引用,删除变量后引用计数归零,内存会被立刻释放,只有存在循环引用的场景才需要主动触发垃圾回收。
关于自动释放的说明
所有主流Python版本都不会自动释放模块作用域下的冗余变量:Python默认不会主动卸载已经导入的模块,模块对象会一直持有所有模块级变量的引用,直到进程退出。只有局部作用域(函数、代码块等)内的变量才会在作用域失效后被自动回收。
内容的提问来源于stack exchange,提问作者Lucas
相关产品推荐
相关产品推荐

