@@ -585,12 +585,20 @@ static void gc_sweep_foreign_objs(void)
585
585
// GC knobs and self-measurement variables
586
586
static int64_t last_gc_total_bytes = 0 ;
587
587
588
+ // max_total_memory is a suggestion. We try very hard to stay
589
+ // under this limit, but we will go above it rather than halting.
588
590
#ifdef _P64
589
591
#define default_collect_interval (5600*1024*sizeof(void*))
590
592
static size_t max_collect_interval = 1250000000UL ;
593
+ // Eventually we can expose this to the user/ci.
594
+ static uint64_t max_total_memory = (uint64_t ) 2 * 1024 * 1024 * 1024 * 1024 * 1024 ;
591
595
#else
592
596
#define default_collect_interval (3200*1024*sizeof(void*))
593
597
static size_t max_collect_interval = 500000000UL ;
598
+ // Work really hard to stay within 2GB
599
+ // Alternative is to risk running out of address space
600
+ // on 32 bit architectures.
601
+ static uint32_t max_total_memory = (uint32_t ) 2 * 1024 * 1024 * 1024 ;
594
602
#endif
595
603
596
604
// global variables for GC stats
@@ -3158,6 +3166,13 @@ static int _jl_gc_collect(jl_ptls_t ptls, jl_gc_collection_t collection)
3158
3166
gc_num .interval = max_collect_interval ;
3159
3167
}
3160
3168
}
3169
+
3170
+ // If the live data outgrows the suggested max_total_memory
3171
+ // we keep going with minimum intervals and full gcs until
3172
+ // we either free some space or get an OOM error.
3173
+ if (live_bytes > max_total_memory ) {
3174
+ sweep_full = 1 ;
3175
+ }
3161
3176
if (gc_sweep_always_full ) {
3162
3177
sweep_full = 1 ;
3163
3178
}
@@ -3237,6 +3252,17 @@ static int _jl_gc_collect(jl_ptls_t ptls, jl_gc_collection_t collection)
3237
3252
if (gc_num .interval < default_collect_interval ) gc_num .interval = default_collect_interval ;
3238
3253
}
3239
3254
3255
+ // We need this for 32 bit but will be useful to set limits on 64 bit
3256
+ if (gc_num .interval + live_bytes > max_total_memory ) {
3257
+ if (live_bytes < max_total_memory ) {
3258
+ gc_num .interval = max_total_memory - live_bytes ;
3259
+ } else {
3260
+ // We can't stay under our goal so let's go back to
3261
+ // the minimum interval and hope things get better
3262
+ gc_num .interval = default_collect_interval ;
3263
+ }
3264
+ }
3265
+
3240
3266
gc_time_summary (sweep_full , t_start , gc_end_t , gc_num .freed , live_bytes , gc_num .interval , pause );
3241
3267
3242
3268
prev_sweep_full = sweep_full ;
0 commit comments