TL / DR:
import gc, sys print len(gc.get_objects())
UPDATE I contacted Python developers on this issue, and indeed, I will not be able to completely unload the module in the next five years. (see link)
Accept that Python really does not support unloading modules for serious, fundamental, insurmountable technical problems in 2.x.
During my recent memleak hunt in my application, I narrowed it down to modules, namely: the inability of garbage to collect an unloaded module. Using any method listed below to unload a module, produces thousands of objects in memory. In other words - I cannot unload a module in Python ...
The rest of the question is an attempt to garbage collect a module somehow.
Try:
import gc import sys sm = sys.modules.copy()
Save a copy of sys.modules to try to restore it later. So these are the basic 4074 objects. We should ideally return to this somehow.
You can import the module:
import httplib print len(gc.get_objects())
We have up to 7K objects without garbage. Try removing httplib from sys.modules .
sys.modules.pop('httplib') gc.collect() print len(gc.get_objects())
Well, that didn't work. Hmm, but is there a link in __main__ ? Oh yeah:
del httplib gc.collect() print len(gc.get_objects())
Hooray, down 300 objects. However, there is no cigar, thus more than 4000 original items. Try to restore sys.modules from the copy.
sys.modules = sm gc.collect() print len(gc.get_objects())
Hmmm, well, that was pointless, no change .. Maybe if we destroy the globals ...
globals().clear() import gc # we need this since gc was in globals() too gc.collect() print len(gc.get_objects()) # 6746 objects in memory
local residents?
locals().clear() import gc # we need this since gc was in globals() too gc.collect() print len(gc.get_objects()) # 6746 objects in memory
What ... what if we imported module inside exec ?
local_dict = {} exec 'import httplib' in local_dict del local_dict gc.collect() print len(gc.get_objects())
Now, dishonestly, he imported it into __main__ , why? He should never have left local_dict ... Argh! We will return to the fully imported httplib . Maybe if we replace it with a dummy object?
from types import ModuleType import sys print len(gc.get_objects())
Bloody ..... !!
sys.modules['httplib'] = ModuleType('httplib') print len(gc.get_objects())
Die cutting modules, die !!
import httplib for attr in dir(httplib): setattr(httplib, attr, None) gc.collect() print len(gc.get_objects())
Well, after all the attempts, the best is +2675 (almost + 50%) from the starting point ... This is from only one module ... This one doesn't even have anything big inside ...
OK, now seriously, where is my mistake? How to unload a module and destroy its contents? Or are there Python modules for one giant memory leak?
Full source in a simpler form for copying: http://gist.github.com/450606