On Sun, 2004-09-19 at 02:54, bulia byak wrote:
> > foo =3D create_foo(); // create a foo
> > ... // do what we need to do with foo
> > bar->withFoo(foo); // can take its own reference if it needs to
> > ... // do anything else we need to do with foo
> > unref_foo(foo); // we should let go of our reference now
> > It's the equivalent of the last line that was missing here.
> I may misunderstand something, but, if we still need that last line,
> how it's better than not having a garbage collector at all? Before you
> needed an explicit free(), now you need an explicit unref() in the
> same place. If it's still not completely automatic, then what's the
unref() is very diffrent from free() -- it says "destroy this object if
nobody else is using it", not just "destroy this object". free() would
never have been appropriate there.
That's the way reference counting has always worked. SPDocuments aren't
yet managed by the garbage collector.
We will still need reference counting in places where gc-managed memory
is referenced by non-gc-managed memory (this is the purpose of
Inkscape::GC::Anchored), but only along that boundary. "Within the
family", refcounts are no longer needed.
SPRepr is a good example of this: SPObjects, which are not gc-managed,
refcount them, but SPReprs no longer need to refcount each other. That
has resulted in significant simplification of the SPRepr code, which is
the desired advantage.
As more classes come to be managed by the collector, less use of
refcounts will be necessary, and we can even use I::G::A less.
> It still eats memory pretty fast as you go through previews. Maybe
> slower than before (I haven't measured that before) but not by much.
> On export, there's no improvement at all (I did measure that before
> and after).
I think the next problem is that I screwed up and GC_invoke_finalizers()
isn't being called in the idle loop like I had intended, so
Inkscape::GC::Finalized objects never get collected.
One of the few I::G::F-derived classes is SPReprDoc, so obviously that
is pretty bad.
It may be simpler to set GC_finalize_on_demand to 0 in
Inkscape::GC::init (so finalizers get called immediately), and not
bother with GC_invoke_finalizers().
 I::G::A does start with an initial reference count of 1 that you
need to "release" (unref), but the requirements are much less stringent
than with refcounts -- e.g. this is safe to do (and probably preferred):
Foo *foo =3D release(new Foo());
release() is a little weaker than unref() -- it just means "it's safe
for the garbage collector to make a decision about this object". Here,
there is no risk of the object being immediately destroyed, since the
garbage collector knows you still have a pointer.
Just be sure to Inkscape::GC::anchor() the object if you stick a pointer
to it in a place that isn't either a local variable or allocated using
the gc-managed allocator.
The only reason I initially anchor I::G::As is that I need it to provide
a drop-in replacement for the existing refcounting schemes that all
start with an initial refcount of 1 -- e.g. sp_repr_ref() and
sp_repr_unref() are now just wrappers for anchor() and release().
 I wanted to defer finalizer execution until the idle loop just to be
extra conservative. It probably won't hurt if finalizers are called at