[Python-Dev] cycle-GC question

Neil Schemenauer nas@arctrix.com
Tue, 19 Dec 2000 00:53:36 -0800


On Tue, Dec 19, 2000 at 09:48:47AM -0500, Guido van Rossum wrote:
> > import rexec
> > while 1:
> >       x = rexec.RExec()
> >       del x
> > 
> > leaks memory at a fantastic rate.
> > 
> > It seems clear (?) that this is due to the call to "set_rexec" at
> > rexec.py:140, which creates a circular reference between the `rexec'
> > and `hooks' objects.  (There's even a nice comment to that effect).

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?

  Neil