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

exec中动态导入模块后内存未释放,求函数结束后清理模块内存方案

问题

在exec中执行模块导入操作后,函数结束时导入的模块(如pandas)占用的内存未被释放,需要在函数结束后清理该函数内所有通过exec导入的模块,且导入的模块名称不固定。

原代码:

from time import sleep

def foo():
    code = """import pandas as pd"""
    exec(code)

if __name__ == '__main__':
    foo()
    sleep(100)
解决方案

要实现函数结束后清理exec导入的模块,核心是隔离exec的命名空间并跟踪、移除本次导入的模块,具体实现如下:

  • 给exec指定独立的局部命名空间字典,避免导入的模块混入全局命名空间
  • 从该命名空间中筛选出模块对象,记录对应的真实模块名(避免别名干扰,比如pd对应的是pandas)
  • 从sys.modules中移除这些模块(仅适用于该模块仅在当前函数内使用的场景,若其他代码依赖该模块,此操作会影响后续使用)
  • 清空局部命名空间,触发垃圾回收机制回收模块占用的内存

示例代码

from time import sleep
import sys
import types

def foo():
    # 创建独立命名空间,用于exec执行代码
    exec_namespace = {}
    code = """import pandas as pd"""
    exec(code, exec_namespace)
    
    # 筛选本次exec导入的模块,记录真实模块名
    imported_modules = []
    for name, obj in exec_namespace.items():
        if isinstance(obj, types.ModuleType):
            mod_name = obj.__name__
            imported_modules.append(mod_name)
    
    # 从sys.modules中移除目标模块
    for mod_name in imported_modules:
        if mod_name in sys.modules:
            del sys.modules[mod_name]
    
    # 清空命名空间,释放内存
    exec_namespace.clear()

if __name__ == '__main__':
    foo()
    sleep(100)

注意事项

  • 若模块被其他代码共享(比如函数外也导入了该模块),移除sys.modules中的模块会导致后续导入重新加载,可能引发异常或性能问题,需根据实际场景判断是否使用
  • 对于模块自动导入的子模块(如pandas内部依赖的子模块),上述方法不会自动清理,若需彻底清理需递归遍历模块依赖,但可能引发不可预知的问题,需谨慎操作

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 05:50:34