[Gc] Heap size and stop-the-world collections

Ludovic Courtès ludovic.courtes at laas.fr
Wed Jul 12 02:09:47 PDT 2006


Hi,

While trying to tweak `libgc' for Guile, I made unexpected (to me)
observations using the `GC_PRINT_STATS' environment variable.

Basically, I had Guile running a program that allocates a small amount
of memory and then discards it (it does that a large number of times, in
a loop).

* If I let it use the default initial heap size, then the debugging
  output shows that the heap size quickly (i.e., after six collections
  or so) reaches a certain value and then no longer grows.  However,
  `libgc' keeps performing stop-the-world collections:

    Initiating full world-stop collection 11 after 948288 allocd bytes
    --> Marking for collection 11 after 948288 allocd bytes + 0 wasted bytes
    Collection 10 finished ---> heapsize = 2060288 bytes
    World-stopped marking took 10 msecs
    Complete collection took 20 msecs

    [...]

    Initiating full world-stop collection 460 after 948288 allocd bytes
    --> Marking for collection 460 after 948288 allocd bytes + 0 wasted bytes
    Collection 459 finished ---> heapsize = 2060288 bytes
    World-stopped marking took 20 msecs
    Complete collection took 20 msecs

  In the end, the number of collections performed is unexpectedly large
  and amounts for a large portion of the program execution time.

* If I set `GC_INITIAL_HEAP_SIZE' to a large value, say 3MB, the same
  behavior is observed but fewer stop-the-world collections are
  performed:

    Initiating full world-stop collection 276 after 1570800 allocd bytes
    --> Marking for collection 276 after 1570800 allocd bytes + 0 wasted bytes
    Collection 275 finished ---> heapsize = 2998272 bytes
    World-stopped marking took 20 msecs
    Complete collection took 20 msecs


There are a couple of things that surprise me:

1. The GC is very conservative: if you don't explicitly provide it with
   a large initial heap, it will apparently not dare grow it.  Is there
   a threshold for heap growth that can be configured?

2. In my example, there is not much to be collected since only a few
   bytes are allocated and discarded in each iteration of the loop while
   the vast majority of the heap remains untouched.  However, the GC
   ends up doing a large number of stop-the-world collections,
   apparently marking and sweeping the _whole_ heap even though just a
   tiny part of it is changing.

   Strangely, setting `GC_ENABLE_INCREMENTAL' actually yields a
   noticeably larger execution time (due to a larger amount of
   stop-the-world marking phases, according to the debugging output).


I can imagine that some of these questions have obvious answers and I
apologize for it.

Thanks,
Ludovic.



More information about the Gc mailing list