TL/博士:import gc, sys
print len(gc.get_objects()) # 4073 objects in memory
# Attempt to unload the module
import httplib
del sys.modules["httplib"]
httplib = None
gc.collect()
print len(gc.get_objects()) # 6745 objects in memory
更新
我已经就这个问题联系过Python开发人员,事实上它完全是not going to be possible to unload a module“在未来五年内”。(见链接)Please accept that Python indeed does not support unloading modules for severe, fundamental, insurmountable, technical problems, in 2.x.
在我最近在我的应用程序中寻找memleak时,我把它缩小到了模块,也就是说,我无法对已卸载的模块进行垃圾收集。使用下面列出的任何方法卸载模块会在内存中留下数千个对象。换句话说-我不能在Python中卸载模块。。。
剩下的问题是试图以某种方式垃圾收集模块。
让我们试试:import gc
import sys
sm = sys.modules.copy() # httplib, which we'll try to unload isn't yet
# in sys.modules, so, this isn't the source of problem
print len(gc.get_objects()) # 4074 objects in memory
让我们保存sys.modules的副本,以便稍后尝试还原它。
所以,这是一个基线4074个对象。我们最好还是回到这个问题上来。
我们导入一个模块:import httplib
print len(gc.get_objects()) # 7063 objects in memory
我们最多有7K个非垃圾对象。
让我们尝试从sys.modules中删除httplib。sys.modules.pop('httplib')
gc.collect()
print len(gc.get_objects()) # 7063 objects in memory
好吧,那没用。嗯,但是__main__中没有引用吗?哦,是的:del httplib
gc.collect()
print len(gc.get_objects()) # 6746 objects in memory
万岁,放下300个物体。尽管如此,没有雪茄,这是超过4000个原始对象的方式。
让我们尝试从副本还原sys.modules。sys.modules = sm
gc.collect()
print len(gc.get_objects()) # 6746 objects in memory
嗯,那是毫无意义的,没有变化。。
如果我们消灭地球人。。。globals().clear()
import gc # we need this since gc was in globals() too
gc.collect()
print len(gc.get_objects()) # 6746 objects in memory
当地人?locals().clear()
import gc # we need this since gc was in globals() too
gc.collect()
print len(gc.get_objects()) # 6746 objects in memory
什么。。如果我们在exec的内部imported一个模块怎么办?local_dict = {}
exec 'import httplib' in local_dict
del local_dict
gc.collect()
print len(gc.get_objects()) # back to 7063 objects in memory
现在,这不公平,它把它导入了__main__,为什么?它不应该离开local_dict。。。啊!我们回到完全导入的httplib。
也许我们用一个虚拟物体代替它?from types import ModuleType
import sys
print len(gc.get_objects()) # 7064 objects in memory
该死的。。。。。!!sys.modules['httplib'] = ModuleType('httplib')
print len(gc.get_objects()) # 7066 objects in memory
模具模块,模具!!import httplib
for attr in dir(httplib):
setattr(httplib, attr, None)
gc.collect()
print len(gc.get_objects()) # 6749 objects in memory
好吧,经过所有的尝试,最好是从起点开始+2675(接近+50%)。。。这只是一个模块。。。里面没有什么大东西。。。
好吧,现在说真的,我的错误在哪里?
如何卸载模块并清除其中的所有内容?
或者Python的模块是一个巨大的内存泄漏?