From f7c67f5c450d30c439b671667baf7dce0a5eb271 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 13 Dec 2015 16:37:56 -0700 Subject: [PATCH] incremental GC: always use generation 1/2 in incremental mode Also, make nursery 1/4 as big in incremental mode, and correspondingly tune the amount of work to perform per collection by 1/4 its old value. Using generation 1/2 reduces fragmentation that would otherwise be increase by a smaller nursery. --- racket/src/racket/gc2/newgc.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 7b4aad3149..4ccbeed7c8 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -254,13 +254,22 @@ MAYBE_UNUSED static void GCVERBOSEprintf(NewGC *gc, const char *fmt, ...) { /* Whether to use a little aging, moving gen-0 objects to a gen-1/2 space; by default, enabled when memory use is high enough: */ -#define AGE_GEN_0_TO_GEN_HALF(gc) ((gc)->memory_in_use > (GEN0_MAX_SIZE * 8)) +#define AGE_GEN_0_TO_GEN_HALF(gc) (((gc)->memory_in_use > (GEN0_MAX_SIZE * 8)) \ + || (gc)->started_incremental) /* Incremental mode */ static int always_collect_incremental_on_minor = 0; -#define INCREMENTAL_COLLECT_FUEL_PER_100M (16 * 1024) -#define INCREMENTAL_REPAIR_FUEL_PER_100M 128 -#define INCREMENTAL_MINOR_REQUEST_DIVISOR 4 +#define INCREMENTAL_COLLECT_FUEL_PER_100M (4 * 1024) +#define INCREMENTAL_REPAIR_FUEL_PER_100M 32 + +/* Shrink the nursery in incremental mode, so that we more frequently + work on a major collection. Tune this parameter in combination with + the fuel parameters above. */ +#define GEN0_INCREMENTAL_MAX_DIVISOR 4 + +/* Factor to shrink incremental-mode fuel when a GC is triggered by + (collect-garbage 'minor): */ +#define INCREMENTAL_MINOR_REQUEST_DIVISOR 1 /* Conservatively force a major GC after a certain number of minor GCs. It should be ok to set this value @@ -2022,6 +2031,10 @@ inline static void reset_nursery(NewGC *gc) || (gc->memory_in_use > GEN0_MAX_SIZE)) /* => overflow */ new_gen0_size = GEN0_MAX_SIZE; + if (gc->started_incremental + && (new_gen0_size > (GEN0_MAX_SIZE / GEN0_INCREMENTAL_MAX_DIVISOR))) + new_gen0_size = GEN0_MAX_SIZE / GEN0_INCREMENTAL_MAX_DIVISOR; + resize_gen0(gc, new_gen0_size); }