Python 3.5.1 C API, the global available available is not destroyed when delete the module

Steven D'Aprano steve+comp.lang.python at pearwood.info
Tue Sep 20 01:49:10 EDT 2016


On Monday 19 September 2016 16:47, dl l wrote:

> Hi,
> 
> I have a app loading python35.dll. Use python API PyImport_AddModule
> to run a py file. And use PyDict_DelItemString to delete the module.
> There is a global vailable in the py file. The global variable is not
> destroyed when calling PyDict_DelItemString to delete the module. That
> cause the memory leak.

See: 

https://bugs.python.org/issue28202

> But it is ok with python33.dll, the global variable can be destroyed
> when calling PyDict_DelItemString to delete the module.

You are calling PyDict_DelItemString on sys.modules, but that won't clear the 
reference to the module if there are any other references to it.


> How to resolve the problem? Is there a workaround? I need to use
> python35.dll and wish the global variable in a module can be released
> automatically when call PyDict_DelItemString to delete the module.

The global object will not be released so long as any other object refers to 
it. If the global object is still alive, it will keep the module alive.

Are you sure that the object has no other references to it? Have you put it in 
a list or dict or some other object?


> Here is the python test code:
> 
> class Simple:
>      def __init__( self ):
>          print('Simple__init__')
>      def __del__( self ):
>          print('Simple__del__')
> 
> simple = Simple()


You cannot rely on the __del__ method running at any specific time. It might 
not run until your application exists.


That test code is not sufficient. How do you call the test code? If you do this 
from main:


import mymodule  # module above
del sys.modules['mymodule']



that will delete the sys.modules cache entry, but the module object is still 
alive. If you are absolutely sure there are no other references to the global 
variable and the module, then it sounds like a leak.

Can you confirm that the gc is enabled?


For a work-around, I can only suggest manually killing the global. What happens 
if you do this:

del sys.modules['mymodule']
mymodule.simple = None
del mymodule


or equivalent?





-- 
Steven
git gets easier once you get the basic idea that branches are homeomorphic 
endofunctors mapping submanifolds of a Hilbert space.




More information about the Python-list mailing list