Skip to content

Updated 32 bit heuristics #44805

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Apr 12, 2022
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