Skip to content
Merged
26 changes: 26 additions & 0 deletions src/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -585,12 +585,20 @@ static void gc_sweep_foreign_objs(void)
// GC knobs and self-measurement variables
static int64_t last_gc_total_bytes = 0;

// max_total_memory is a suggestion. We try very hard to stay
// under this limit, but we will go above it rather than halting.
#ifdef _P64
#define default_collect_interval (5600*1024*sizeof(void*))
static size_t max_collect_interval = 1250000000UL;
// Eventually we can expose this to the user/ci.
static uint64_t max_total_memory = (uint64_t) 2 * 1024 * 1024 * 1024 * 1024 * 1024;
#else
#define default_collect_interval (3200*1024*sizeof(void*))
static size_t max_collect_interval = 500000000UL;
// Work really hard to stay within 2GB
// Alternative is to risk running out of address space
// on 32 bit architectures.
static uint32_t max_total_memory = (uint32_t) 2 * 1024 * 1024 * 1024;
#endif

// global variables for GC stats
Expand Down Expand Up @@ -3158,6 +3166,13 @@ static int _jl_gc_collect(jl_ptls_t ptls, jl_gc_collection_t collection)
gc_num.interval = max_collect_interval;
}
}

// If the live data outgrows the suggested max_total_memory
// we keep going with minimum intervals and full gcs until
// we either free some space or get an OOM error.
if (live_bytes > max_total_memory) {
sweep_full = 1;
}
if (gc_sweep_always_full) {
sweep_full = 1;
}
Expand Down Expand Up @@ -3237,6 +3252,17 @@ static int _jl_gc_collect(jl_ptls_t ptls, jl_gc_collection_t collection)
if (gc_num.interval < default_collect_interval) gc_num.interval = default_collect_interval;
}

// We need this for 32 bit but will be useful to set limits on 64 bit
if (gc_num.interval + live_bytes > max_total_memory) {
if (live_bytes < max_total_memory) {
gc_num.interval = max_total_memory - live_bytes;
} else {
// We can't stay under our goal so let's go back to
// the minimum interval and hope things get better
gc_num.interval = default_collect_interval;
}
}

gc_time_summary(sweep_full, t_start, gc_end_t, gc_num.freed, live_bytes, gc_num.interval, pause);

prev_sweep_full = sweep_full;
Expand Down