如果在命名空间中导入Python模块,是否可以可靠地取消导入?

问题描述

| 基本上,我的运行时间很长,我希望能够通过gc取消导入模块并恢复内存。我已经阅读了有关删除模块的信息,该如何卸载(重新加载)python模块?似乎仍然有悬而未决的引用阻塞了gc。 但是,如果仅在名称空间中导入和使用模块,该怎么办?换句话说,是这样的:
ns = {}
exec somecode in ns
然后,我将清理名称空间内的sys.modules并通过删除名称空间本身结束。 那会释放内存以便在cpython中重用吗? 如果不是,那么是否可以使用ctypes访问Python C API的某些部分来实现此目的? 最终结果的重要部分是释放内存,以便运行数周或数月的进程可以可靠地取消导入模块而无需重新加载它。当然,完全有可能在该时间段内多次加载和卸载任何给定的模块。我假设模块在加载时可以创建大量对象,并且正常的清理(sys.modules和del)会将这些对象永久保留在内存中。 Jochen:是的,我可以通过多种方式解决此问题,但是我对探索Python的局限性感兴趣。     

解决方法

        要取消导入模块,您需要确保已删除所有对该模块的引用。这意味着您必须从导入该模块的所有模块中删除引用,从“ 1”中删除该引用,删除对该模块中定义的任何函数或类的任何引用,并删除对作为模块中定义的类实例的对象的所有引用。 在几乎所有情况下,这都不是值得的,它要花费相对较少的内存来检索。如果您真的想尝试此操作,那么
gc.get_referrers()
可能会有用,因为您可以删除模块中除一个已知引用以外的所有内容,然后回溯以查找仍然引用该模块的内容。     ,        如果您真正想要的是避免内存泄漏,那么最好的选择是安排在正常状态下以正常方式一次导入模块一次。无论模块以后被导入多少次,它都不会占用更多的内存,因为导入机制只会继续返回相同的模块。 如果由于某种原因,这仍然不合适,比如说模块是动态创建的,只需要使用一次,ѭ4isn当然不是解决方案。您应该考虑使用替代执行模型,也许会派生新流程。     

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...