[Python-Dev] Cyclic GC issues
Nick Bastin
nbastin at opnet.com
Mon Oct 11 21:14:52 CEST 2004
On Oct 11, 2004, at 2:59 AM, Jason Evans wrote:
>>> Working around this in Crux requires a lot of extra reference
>>> counting
>>> complexity, because there are three different cases for reference
>>> counts, depending on how many members there are in a ring (1, 2,
>>> or 3+
>>> members).
>>
>> Why is that? Just DECREF every PyObject* in "self", then set the
>> PyObject* to NULL. No need for any additional reference counts.
>
> The low level tree code is implemented completely separately from the
> Python object wrapper code. This means that, for example, the Python
> "Node" object does not actually store PyObject* pointers to Ring
> objects;
> instead it uses the low level tree code to find out what Ring objects
> are
> attached to it. Crux was designed this way in order to be able to
> implement various low level algorithms such that they never have to
> call
> interpreter-related code. As such, reference breaking code must
> actually
> tear down the low level tree in such a way that it is always
> "consistent"
> (simply setting pointers to NULL doesn't fit well with this way of
> doing
> things).
You've now reached the point where the Python-GC-ease-of-implementation
breaks down. We have encountered the same problem - the GC is fine as
long as you're solely extending Python, but if you're embedding it,
chances are you'll encounter some interesting issues like this along
the way. It's not that you can't make it work - you can, but need to
do a lot more work yourself. Basically, if I understand you correctly
(and I may not be), there are times when you do not want tp_dealloc to
actually destroy the low-level data structure, because somebody else
(not living in the Python reference-counted world) isn't done with it
yet. The problem is in knowing when those times are, and when they
aren't. In this case, you may need to implement basic reference
counting in your own low-level data structures, so you know when you're
really done with a ring and ready to destroy it. The other option is
to attempt to make sure that you're not creating cycles (in python) and
avoid interfacing with GC entirely, but that may not be possible in
your case.
--
Nick
More information about the Python-Dev
mailing list