[Gc] Patch resubmission: Default stop_func
hans.boehm at hp.com
Mon Sep 21 22:17:22 PDT 2009
I just got a chance to look at this, and I don't quite understand the logic.
GC_collect_or_expand() is called in cases in which we need more memory, but none is available in the existing heap. I think your patch changes the nonincremental case to collect with a timeout here. If it actually times out, you will end up growing the heap. The problem is that for a long running application with fixed space requirements, this will probably happen regularly, and I suspect the heap will grow without bounds, since everytime it runs out, there is some probability it will grow the heap even if there would have been plenty of space after collection.
This isn't critical, since none of this applies if you don't use the new functionality. But I wonder what the intent was, and if this is really useful as is. At least we should document the hazards.
I really don't think there's a safe way to use GC_try_to_collect that doesn't involve collecting before you're out of memory.
> -----Original Message-----
> From: gc-bounces at napali.hpl.hp.com
> [mailto:gc-bounces at napali.hpl.hp.com] On Behalf Of Ivan Maidanski
> Sent: Friday, September 11, 2009 6:32 AM
> To: gc at napali.hpl.hp.com
> Subject: [Gc] Patch resubmission: Default stop_func
> This suggested patch (ivmai129.diff), superseding diff47 [Nov
> 20], introduces the default stop_func used on implicitly
> trigged collections (unless handling OOM, of course). For
> more info, see (the first 2 paragraphs):
> Note: the default stop_func is also used for GC_gcollect() -
> this is a bit arguable but I think it's more logical
> (explicit fn is used for GC_try_to_collect(), implicit
> default stop_func is used for collections trigged by other
> means) and more useful (eg., a timeout policy could be
> introduce to an existing application by just adding
> GC_set_stop_func(fn) instead of replacing all GC_gcollect()
> calls with something like GC_try_to_collect(GC_get_stop_func())).
> ChangeLog entries:
> * alloc.c (GC_default_stop_func): New static variable
> to GC_never_stop_func).
> * alloc.c (GC_set_stop_func, GC_get_stop_func): New function.
> * alloc.c (GC_timeout_stop_func): Define as GC_default_stop_func
> (instead of GC_never_stop_func) if SMALL_CONFIG (or NO_CLOCK),
> else call GC_default_stop_func() before getting "current_time".
> * alloc.c (GC_maybe_gc): Expand GC_gcollect_inner() macro (for
> FIXME comment).
> * alloc.c (GC_maybe_gc, GC_collect_a_little_inner): add
> FIXME for
> replacing GC_never_stop_func with GC_default_stop_func (if
> * alloc.c (GC_gcollect): Use GC_default_stop_func.
> * alloc.c (GC_collect_or_expand): Use GC_default_stop_func
> (instead of GC_never_stop_func) unless it is trigged
> due to out of
> memory; don't increment GC_fail_count and don't output warning
> (before trying to collect again) in case the collection has been
> interrupted (by GC_default_stop_func) and the heap expansion has
> failed too.
> * include/gc.h (GC_set_stop_func, GC_get_stop_func):
> New function
More information about the Gc