Manually prompting garbage collection

Kyle Lanclos lanclos at ucolick.org
Thu Jul 17 01:09:11 CEST 2008


I've done a lot of web searching, a fair bit of C-source reading, and
quite a lot of miscellaneous head scratching, and I find that I am not
necessarily closer to an ideal solution.

I have a Python/C interface layer that essentially does the following:

Py_XDECREF (some_callback);
closeService (some_service);
return;

The problem, of course, is that way back in my Python layer, I have
Objects that are poised to be de-allocated due to the Py_XDECREF call
above; those Objects have __del__ () methods that invoke calls to the
service that is about to be closed in the second line above.

I want to modify the above sequence to manually prompt Python's garbage
collection routine(s) to take over (performance is not an issue here),
similar to the following:

Py_XDECREF (some_callback);
PyCollect_Garbage ();
closeService (some_service);
return;

Is that possible?

I can work around this with additional convoluted tracking of the services
in the C layer, but the problem would disappear entirely if the garbage
collection could be explicitly invoked. I suspect the likely workaround
would involve returning from the above C function, letting Whatever happen
a few times, and only invoking the real closeServce () after I've returned
to the C layer. To wit:

Py_XDECREF (some_callback);
markForClosure (some_service);
return;

(( ...time passes in Python-space, and a C function is invoked... ))

if ( servicesNeedClosing ()) { closeServices (); }
return;

I would prefer, however, an explicit solution, as the above workaround
continues to rely on the assumption that garbage collection occurs
magically at some point when I'm not paying attention.

Solutions I've read about, and/or attempted, and am not wholly interested
in hearing more about:

1. Don't use __del__ methods.

   I'm using __del__ methods, which are otherwise doing the right thing
   in non-sequence-sensitive situations, so this option is off the table.

2. Don't assume that __del__ methods will be invoked in a timely
   fashion.

   I'm not making this assumption, but rather, I would like to
   *explicitly* assert that garbage collection has occurred.

3. Use the gc module (or PyGC_Collect).

   These appear to only address situations with circular references,
   which are not my problem-- the Py_XDECREF call makes the right thing
   happen, it's just that the garbage collection happens *after* the
   service has been properly closed. I've tried inserting calls to
   PyGC_Collect (including an invocation of "while (PyGC_Collect() > 0)")
   with no change in behavior.

Suggestions are welcome.

Cheers,

--Kyle



More information about the Python-list mailing list