[Python-Dev] cycle-GC question

Charles G Waldman cgw@fnal.gov
Tue, 19 Dec 2000 10:06:06 -0600 (CST)


Neil Schemenauer writes:
 > 
 > Line 140 is not the only place a circular reference is created.
 > There is another one which is trickier to find:
 > 
 >     def add_module(self, mname):
 >         if self.modules.has_key(mname):
 >             return self.modules[mname]
 >         self.modules[mname] = m = self.hooks.new_module(mname)
 >         m.__builtins__ = self.modules['__builtin__']
 >         return m
 > 
 > If the module being added is __builtin__ then m.__builtins__ = m.
 > The GC currently doesn't track modules.  I guess it should.  It
 > might be possible to avoid this circular reference but I don't
 > know enough about how RExec works.  Would something like:
 > 
 >     def add_module(self, mname):
 >         if self.modules.has_key(mname):
 >             return self.modules[mname]
 >         self.modules[mname] = m = self.hooks.new_module(mname)
 >         if mname != '__builtin__':
 >             m.__builtins__ = self.modules['__builtin__']
 >         return m
 >     
 > do the trick?

No... if you change "add_module" in exactly the way you suggest
(without worrying about whether it breaks the functionality of rexec!)
and run the test

while 1:
      rexec.REXec()

you will find that it still leaks memory at a prodigious rate.

So, (unless there is yet another module-level cyclic reference) I
don't think this theory explains the problem.