[IronPython] clr.AddReference effect how GC work ?!?!?!?

Curt Hagenlocher curt at hagenlocher.org
Thu Apr 24 01:44:46 CEST 2008

On Wed, Apr 23, 2008 at 12:23 AM, Sakesun Roykiattisak
<sakesun at boonthavorn.com> wrote:
>    My today attempt to fight with over-memory usage in my IronPython
> server application, reveal a very strange behavior of IronPython
> (both 1.1 and 2.0b)  I'll demonstrate with the following script: "loopit.py"

This is actually a really fun testbed for examining the behavior of
the finalizer queue in the face of various conditions.  After a bit
more trial and error, I've got a theory for what happens.

clr.AddReference('System') does something which creates a short-lived
COM object that was nonetheless briefly accessible through the CLR.
When garbage is next collected, this object has no references left.
It's got a finalizer, though, because it's a COM object and someone
needs to make that last call to IUnknown::Release.  But because it was
created from a single-threaded apartment, the GC won't schedule the
finalizer to be run while the apartment from which it was created is

Somehow -- maybe just because the finalization queue literally is a
queue -- no other finalizer can be run while the system is waiting to
run this one.

In the original example, if you "GC.Collect()" and
"Thread.CurrentThread.Join()" immediately after the call to
clr.AddReference, you force finalization of this COM object and any
remaining finalization happens normally as subsequent calls to
GC.Collect() are made.

If this theory is roughly correct, then the same problem can be
triggered by just about any code that inadvertently calls
CoCreateInstance from an STA thread.  This would include use of the
WebClient and SqlClient classes, iirc.  And in that sense, it's not an
IronPython problem at all, though it's exacerbated by the fact that
the IP console is STA "by default".

Curt Hagenlocher
curt at hagenlocher.org

More information about the Ironpython-users mailing list