Skip to content

Commit 468c057

Browse files
authored
GC Always Full Flag (JuliaLang#58713)
This used to be an environment variable (`JULIA_GC_NO_GENERATIONAL`) that could only be enabled if Julia was built with `WITH_GC_DEBUG_ENV`. People benchmarking GC may want to disable generational behavior in non-debug builds as well. This PR introduces `gc-sweep-always-full` as a hidden command-line-option. It also moves the docstrings for `--hard-heap-limit` and `--heap-target-increment` into `opts_hidden`, as it should have been done in the original PR.
1 parent 6121477 commit 468c057

File tree

8 files changed

+31
-27
lines changed

8 files changed

+31
-27
lines changed

base/options.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ struct JLOptions
6666
trim::Int8
6767
task_metrics::Int8
6868
timeout_for_safepoint_straggler_s::Int16
69+
gc_sweep_always_full::Int8
6970
end
7071

7172
# This runs early in the sysimage != is not defined yet

doc/src/manual/environment-variables.md

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -530,17 +530,6 @@ Allows you to enable or disable zones for a specific Julia run.
530530
For instance, setting the variable to `+GC,-INFERENCE` will enable the `GC` zones and disable
531531
the `INFERENCE` zones. See [Dynamically Enabling and Disabling Zones](@ref).
532532

533-
### [`JULIA_GC_NO_GENERATIONAL`](@id JULIA_GC_NO_GENERATIONAL)
534-
535-
If set to anything besides `0`, then the Julia garbage collector never performs
536-
"quick sweeps" of memory.
537-
538-
!!! note
539-
540-
This environment variable only has an effect if Julia was compiled with
541-
garbage-collection debugging (that is, if `WITH_GC_DEBUG_ENV` is set to `1`
542-
in the build configuration).
543-
544533
### [`JULIA_GC_WAIT_FOR_DEBUGGER`](@id JULIA_GC_WAIT_FOR_DEBUGGER)
545534

546535
If set to anything besides `0`, then the Julia garbage collector will wait for

src/gc-debug.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -892,10 +892,7 @@ void gc_heuristics_summary(
892892
void jl_gc_debug_init(void)
893893
{
894894
#ifdef GC_DEBUG_ENV
895-
char *env = getenv("JULIA_GC_NO_GENERATIONAL");
896-
if (env && strcmp(env, "0") != 0)
897-
jl_gc_debug_env.always_full = 1;
898-
env = getenv("JULIA_GC_WAIT_FOR_DEBUGGER");
895+
char *env = getenv("JULIA_GC_WAIT_FOR_DEBUGGER");
899896
jl_gc_debug_env.wait_for_debugger = env && strcmp(env, "0") != 0;
900897
gc_debug_alloc_init(&jl_gc_debug_env.pool, "POOL");
901898
gc_debug_alloc_init(&jl_gc_debug_env.other, "OTHER");

src/gc-stock.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3155,7 +3155,7 @@ static int _jl_gc_collect(jl_ptls_t ptls, jl_gc_collection_t collection) JL_NOTS
31553155
// If the live data outgrows the suggested max_total_memory
31563156
// we keep going with minimum intervals and full gcs until
31573157
// we either free some space or get an OOM error.
3158-
if (gc_sweep_always_full) {
3158+
if (jl_options.gc_sweep_always_full) {
31593159
sweep_full = 1;
31603160
gc_count_full_sweep_reason(FULL_SWEEP_REASON_SWEEP_ALWAYS_FULL);
31613161
}

src/gc-stock.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ typedef struct {
4444
} jl_alloc_num_t;
4545

4646
typedef struct {
47-
int always_full;
4847
int wait_for_debugger;
4948
jl_alloc_num_t pool;
5049
jl_alloc_num_t other;
@@ -647,14 +646,12 @@ NOINLINE void gc_mark_loop_unwind(jl_ptls_t ptls, jl_gc_markqueue_t *mq, int off
647646

648647
#ifdef GC_DEBUG_ENV
649648
JL_DLLEXPORT extern jl_gc_debug_env_t jl_gc_debug_env;
650-
#define gc_sweep_always_full jl_gc_debug_env.always_full
651649
int jl_gc_debug_check_other(void);
652650
int gc_debug_check_pool(void);
653651
void jl_gc_debug_print(void);
654652
void gc_scrub_record_task(jl_task_t *ta) JL_NOTSAFEPOINT;
655653
void gc_scrub(void);
656654
#else
657-
#define gc_sweep_always_full 0
658655
static inline int jl_gc_debug_check_other(void)
659656
{
660657
return 0;

src/jloptions.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ JL_DLLEXPORT void jl_init_options(void)
159159
JL_TRIM_NO, // trim
160160
0, // task_metrics
161161
-1, // timeout_for_safepoint_straggler_s
162+
0, // gc_sweep_always_full
162163
};
163164
jl_options_initialized = 1;
164165
}
@@ -293,14 +294,6 @@ static const char opts[] =
293294
" number of bytes, optionally in units of: B, K (kibibytes),\n"
294295
" M (mebibytes), G (gibibytes), T (tebibytes), or % (percentage\n"
295296
" of physical memory).\n\n"
296-
" --hard-heap-limit=<size>[<unit>] Set a hard limit on the heap size: if we ever go above this\n"
297-
" limit, we will abort. The value may be specified as a\n"
298-
" number of bytes, optionally in units of: B, K (kibibytes),\n"
299-
" M (mebibytes), G (gibibytes) or T (tebibytes).\n\n"
300-
" --heap-target-increment=<size>[<unit>] Set an upper bound on how much the heap target\n"
301-
" can increase between consecutive collections. The value may be\n"
302-
" specified as a number of bytes, optionally in units of: B,\n"
303-
" K (kibibytes), M (mebibytes), G (gibibytes) or T (tebibytes).\n\n"
304297
;
305298

306299
static const char opts_hidden[] =
@@ -344,6 +337,18 @@ static const char opts_hidden[] =
344337
" and can throw errors. With unsafe-warn warnings will be\n"
345338
" printed for dynamic call sites that might lead to such\n"
346339
" errors. In safe mode compile-time errors are given instead.\n"
340+
" --hard-heap-limit=<size>[<unit>] Set a hard limit on the heap size: if we ever\n"
341+
" go above this limit, we will abort. The value\n"
342+
" may be specified as a number of bytes,\n"
343+
" optionally in units of: B, K (kibibytes),\n"
344+
" M (mebibytes), G (gibibytes) or T (tebibytes).\n"
345+
" --heap-target-increment=<size>[<unit>] Set an upper bound on how much the heap\n"
346+
" target can increase between consecutive\n"
347+
" collections. The value may be specified as\n"
348+
" a number of bytes, optionally in units of:\n"
349+
" B, K (kibibytes), M (mebibytes), G (gibibytes)\n"
350+
" or T (tebibytes).\n"
351+
" --gc-sweep-always-full Makes the GC always do a full sweep of the heap\n"
347352
;
348353

349354
JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp)
@@ -394,6 +399,7 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp)
394399
opt_heap_size_hint,
395400
opt_hard_heap_limit,
396401
opt_heap_target_increment,
402+
opt_gc_sweep_always_full,
397403
opt_gc_threads,
398404
opt_permalloc_pkgimg,
399405
opt_trim,
@@ -467,6 +473,7 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp)
467473
{ "heap-size-hint", required_argument, 0, opt_heap_size_hint },
468474
{ "hard-heap-limit", required_argument, 0, opt_hard_heap_limit },
469475
{ "heap-target-increment", required_argument, 0, opt_heap_target_increment },
476+
{ "gc-sweep-always-full", no_argument, 0, opt_gc_sweep_always_full },
470477
{ "trim", optional_argument, 0, opt_trim },
471478
{ 0, 0, 0, 0 }
472479
};
@@ -1027,6 +1034,9 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp)
10271034
jl_errorf("julia: --timeout-for-safepoint-straggler=<seconds>; seconds must be an integer between 1 and %d", INT16_MAX);
10281035
jl_options.timeout_for_safepoint_straggler_s = (int16_t)timeout;
10291036
break;
1037+
case opt_gc_sweep_always_full:
1038+
jl_options.gc_sweep_always_full = 1;
1039+
break;
10301040
case opt_trim:
10311041
if (optarg == NULL || !strcmp(optarg,"safe"))
10321042
jl_options.trim = JL_TRIM_SAFE;

src/jloptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ typedef struct {
7070
int8_t trim;
7171
int8_t task_metrics;
7272
int16_t timeout_for_safepoint_straggler_s;
73+
int8_t gc_sweep_always_full;
7374
} jl_options_t;
7475

7576
#endif

test/gc.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,15 @@ end
8282
@testset "Full GC reasons" begin
8383
full_sweep_reasons_test()
8484
end
85+
86+
@testset "GC Always Full" begin
87+
prog = "using Test;\n
88+
for _ in 1:10; GC.gc(); end;\n
89+
reasons = Base.full_sweep_reasons();\n
90+
@test reasons[:FULL_SWEEP_REASON_SWEEP_ALWAYS_FULL] >= 10;"
91+
cmd = `$(Base.julia_cmd()) --depwarn=error --startup-file=no --gc-sweep-always-full -e $prog`
92+
@test success(cmd)
93+
end
8594
end
8695

8796
@testset "Base.GC docstrings" begin

0 commit comments

Comments
 (0)