Python vs Java garbage collection?

maney at pobox.com maney at pobox.com
Sun Dec 29 01:00:28 EST 2002


"Martin v. L?wis" <martin at v.loewis.de> wrote:
> Martin Maney wrote:
>> Yes, I assumed that that was at least a good part of the reason Jython
>> abandonded the traditional ref counting of CPython.  This was also
>> meant to be implicit agreement with your perhaps rhetorical question to
>> the previous poster.  
> 
> It was 50% rhetorical, as I'm convinced there is no satisfying answer; I 
>  assumed a 50% chance that Bengt tries to answer (and was surprised 
> that somebody else answered).

Being alive consists largely of being surprised, no?  :-)

I have been surprised at how the examination of my own notions about
this have been shifted by these discussions.  A little while ago I
would have said (or maybe did say?) that the problem was only due to
sloppiness; with the latest insights offerred by the lack of promises
by even pre-Jython documentation, I seem to be left more or less won
over to the "reliable, timely finalizers are nice" side even as any
hope that relying on that doesn't make one's code unportable to other
(non-CPython) implementations has all but vanished.  :-(

It was somewhere in that process of change, as I was examining both the
theory as well as looking closely at some of my own natural Python
coding habits, that Bengt's suggestion came along.  I thought I saw
what might be a viable compromise between CPython's de facto behavior
and the semantics of finalization that the language definition (no,
it's not as thorough - or as unalterable - as an ISO spec, but it's
what we have as guidance for the long run) guarantees, which is of
course a guarantee of nothing.

So it is in some ways an accident that I've been discussing this in
terms of Jython, although as the most discussed non-CPython
implementation, and having very different performance w.r.t.
finalization, it's an obvious attractor for any concrete discussion. 
It does muddy the water in some respects, as it continues to conflate
object finalization with the scavenging of memory.  Of course the two
are not entirely separate, but CPython and Jython are alike, unless I
am misunderstanding some of this yet, in linking the two very closely
in time.  You finalize and then you scavenge more or less immediately. 
That order is required, but not the temporal propinquity.

> It is often concidered as a strength of Jython that you can integrate so 
> easily with the Java library; this may involve call-backs from Java to 
> Python, which in turn requires that "pure" Java object hold references 
> to Python objects.

Which may or may not be very relevant to a selective ref counting for
finalization scheme.  I don't think there's much more to say about that
unless we get empirical data from Jython users about the patterns of
use of Python objects that need timely finalization: are they often
shared between languages, or is that usually avoidable?

It does in any case complicate the issue.

> Can you please explain how these schemes work? In CPython, all objects 
> are of type PyObject*, and Py_INCREF and Py_DECREF are macros that 
> access the internal structure of a PyObject, which contains the member 
> ob_refcount.

Okay,  Assuming that CPython were to wish to switch to a
non-ref-counting gc; assuming that there was some advantage to using
that, so that non-counted objects would be the default; assuming that a
mechanism not here described is introduced to allow objects to be
created as ref-counted when the tighter finalization timing were
important.

>From a perhaps superficial understanding of this, it looks like it
would be easy enough to implement the INCREF/DECREF changes for this. 
It seems likely to make the generated machine code simpler to use a
sentinel value in the ob_refcnt field, and the most convenient value is
probably zero.  The macros would then look like this (without debug
aids):

#define Py_INCREF(op) if ((op)->ob_refcnt != 0) ((op)->ob_refcnt++)
#define Py_DECREF(op) \
        if ((op)->ob_refcnt == 0 || --(op)->ob_refcnt != 0) \
                ; \
        else \
                _Py_Dealloc((PyObject *)(op))

BTW, why is DECREF written in that unnatural way?

This adds a little code size to both, and probably makes INCREF a
little slower; DECREF should be a trifle faster for the majority of
objects that are not ref-counted, and it might even turn out to be
worthwhile to move the decrement to a utility function to reclaim the
code space if ref-counting were infrequently enough used.  Or would the
call to __del__ be inlined now that this code is no longer responsible
for scavenging the memory?

> This doesn't translate to Jython at all, since Jython uses native VM 
> instructions and the native VM stack to manipulate object references, be 
> it references to Jython objects, or to "pure" Java objects.

I don't understand what you're saying here at all.  Do you really mean
that a Java programmer *cannot* implement reference counting in a way
analogous to what can be done in, say, C++?  Of course there are issues
about letting references escape into non-counted contexts, and in Java
one wouldn't be counting for the purpose of scavenging memory.



More information about the Python-list mailing list