[Gc] Problem with finalizers
Hans.Boehm at hp.com
Mon May 7 21:30:32 PDT 2007
On Thu, 3 May 2007, Lothar Scholz wrote:
> Hello Bruce,
> Thursday, May 3, 2007, 6:26:15 AM, you wrote:
> BH> From: "Bruce Hoult" <bruce at hoult.org>
> BH> On 5/3/07, Lothar Scholz <scholz at scriptolutions.com> wrote:
> >> i have written a test program that works fine. It just allocates 400
> >> objectes in a loop 200 of them having finalizers. This loop is
> >> repeated many times. No references to create objects are held after
> >> the loop.
> >> Now the strange behaviour:
> >> Without finalizers its fast, but with finalizers the whole app stops
> >> many times in the gc (as i guess) for seconds. Instead of 200 ms it
> >> takes about 22 sec to finish. The finalizer function is empty and
> >> there is no CPU load during the stops.
> BH> I've got $100 says you're swapping.
> Good advise for you: Be more carefull with your money :-)
> The program just takes 5 MB on a 2 GB (Core2Duo) system. CPU usage is
> below 5% with a peak at 9%.
> I wouldn't be surprised if somethings happen or the whole thing
> deadlocks. But it just stops for a few seconds and then continues.
> And it's just the one i uncomment the
> line it all works fine.
> BH> It takes memory to record the fact than an object has a finalizer.
> BH> Having a finalizer prevents objects from being collected in the first
> BH> GC after they become unreferenced, and they have to stay until the 2nd
> BH> one.
> Maybe Hans can tell me if it is okay to call GC_free from inside the
> finalizer to tell the GC that it is not referenced again.
> I also tried it with 'GC_finalize_on_demand' set to 0 and 1. No
> difference in behaviour.
If you're willing to post the test program, I can try it under Linux,
where I'm more familiar with profiling tools, etc.
Finalization does slow things down dramatically; something close to a
factor of 10 is probably normal when everything is finalizable. But this
sounds like it's more than that.
There are other potential issues if you build chains of finalizable
objects. Anything that is reachable from a finalizable object won't
be finalized until the next GC cycle, and collected after the second
cycle. Long chains are finalized one per cycle. (Standard solution:
instead point to a small object that only contains the data needed
for finalization and finalize only that.)
Another possibility is that there is a bug in the Windows synchronization
code, and it waits much too long someplace. It might also be worth trying
the 7.0 CVS code and seeing how that compares.
Running both versions with the GC_PRINT_STATS environment variable defined
and looking at the log files might also give you some hints.
It should be OK to call GC_free from inside the finalizer. (Finalizers
are enqueued and then run outside the collector. That's part of the
reason they're expensive.) However I would be surprised if that helped.
If the object is small, I'd expect it to hurt slightly.
More information about the Gc