Skip to content

Commit

Permalink
add ability to specify heap size hint as a percent
Browse files Browse the repository at this point in the history
also fix overflowed subtraction with size hints < 250mb
  • Loading branch information
JeffBezanson committed Jan 31, 2024
1 parent 08e3c2e commit ec4182e
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 11 deletions.
4 changes: 2 additions & 2 deletions doc/man/julia.1
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,8 @@ fallbacks to the latest compatible BugReporting.jl if not. For more information,

.TP
--heap-size-hint=<size>
Forces garbage collection if memory usage is higher than that value. The memory hint might be
specified in megabytes (500M) or gigabytes (1.5G)
Forces garbage collection if memory usage is higher than that value. The value can be
specified in units of K, M, G, T, or % of physical memory.

.TP
--compile={yes*|no|all|min}
Expand Down
18 changes: 13 additions & 5 deletions src/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -4037,14 +4037,22 @@ void jl_gc_init(void)
gc_num.max_pause = 0;
gc_num.max_memory = 0;

uint64_t mem_reserve = 250*1024*1024; // LLVM + other libraries need some amount of memory
uint64_t min_heap_size_hint = mem_reserve + 1*1024*1024;
uint64_t hint = jl_options.heap_size_hint;
#ifdef _P64
total_mem = uv_get_total_memory();
uint64_t constrained_mem = uv_get_constrained_memory();
if (constrained_mem > 0 && constrained_mem < total_mem)
jl_gc_set_max_memory(constrained_mem - 250*1024*1024); // LLVM + other libraries need some amount of memory
if (hint == 0) {
uint64_t constrained_mem = uv_get_constrained_memory();
if (constrained_mem > 0 && constrained_mem < total_mem)
hint = constrained_mem;
}
#endif
if (jl_options.heap_size_hint)
jl_gc_set_max_memory(jl_options.heap_size_hint - 250*1024*1024);
if (hint) {
if (hint < min_heap_size_hint)
hint = min_heap_size_hint;
jl_gc_set_max_memory(hint - mem_reserve);
}

t_start = jl_hrtime();
}
Expand Down
14 changes: 12 additions & 2 deletions src/jloptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ static const char opts[] =
" --bug-report=help.\n\n"

" --heap-size-hint=<size> Forces garbage collection if memory usage is higher than that value.\n"
" The memory hint might be specified in megabytes(500M) or gigabytes(1G)\n\n"
" The value can be specified in units of K, M, G, T, or % of physical memory.\n\n"
;

static const char opts_hidden[] =
Expand Down Expand Up @@ -821,14 +821,24 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp)
case 'T':
multiplier <<= 40;
break;
case '%':
if (value > 100)
jl_errorf("julia: invalid percentage specified in --heap-size-hint");
uint64_t mem = uv_get_total_memory();
uint64_t cmem = uv_get_constrained_memory();
if (cmem > 0 && cmem < mem)
mem = cmem;
multiplier = mem/100;
break;
default:
jl_errorf("julia: invalid unit specified in --heap-size-hint");
break;
}
jl_options.heap_size_hint = (uint64_t)(value * multiplier);
}
}
if (jl_options.heap_size_hint == 0)
jl_errorf("julia: invalid argument to --heap-size-hint without memory size specified");
jl_errorf("julia: invalid memory size specified in --heap-size-hint");

break;
case opt_gc_threads:
Expand Down
18 changes: 16 additions & 2 deletions test/cmdlineargs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1043,8 +1043,22 @@ end
@test lines[3] == "foo"
@test lines[4] == "bar"
end
#heap-size-hint, we reserve 250 MB for non GC memory (llvm, etc.)
@test readchomp(`$(Base.julia_cmd()) --startup-file=no --heap-size-hint=500M -e "println(@ccall jl_gc_get_max_memory()::UInt64)"`) == "$((500-250)*1024*1024)"
end

@testset "heap size hint" begin
#heap-size-hint, we reserve 250 MB for non GC memory (llvm, etc.)
@test readchomp(`$(Base.julia_cmd()) --startup-file=no --heap-size-hint=500M -e "println(@ccall jl_gc_get_max_memory()::UInt64)"`) == "$((500-250)*1024*1024)"

mem = ccall(:uv_get_total_memory, UInt64, ())
cmem = ccall(:uv_get_constrained_memory, UInt64, ())
if cmem > 0 && cmem < mem
mem = cmem
end
maxmem = parse(Int, readchomp(`$(Base.julia_cmd()) --startup-file=no --heap-size-hint=25% -e "println(@ccall jl_gc_get_max_memory()::UInt64)"`))
hint = max(0.25mem, 251*1024*1024)
@test abs(maxmem - (hint - 250*1024*1024))/maxmem < 0.01

@test readchomp(`$(Base.julia_cmd()) --startup-file=no --heap-size-hint=10M -e "println(@ccall jl_gc_get_max_memory()::UInt64)"`) == "$(1*1024*1024)"
end

## `Main.main` entrypoint
Expand Down

0 comments on commit ec4182e

Please sign in to comment.