Skip to content
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

add ability to specify heap size hint as a percent #52979

Merged
merged 1 commit into from
Feb 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
22 changes: 20 additions & 2 deletions test/cmdlineargs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1043,8 +1043,26 @@ 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(UInt64, readchomp(`$(Base.julia_cmd()) --startup-file=no --heap-size-hint=25% -e "println(@ccall jl_gc_get_max_memory()::UInt64)"`))
hint = max(mem÷4, 251*1024*1024) - 250*1024*1024
MAX32HEAP = 1536 * 1024 * 1024
if Int === Int32 && hint > MAX32HEAP
hint = MAX32HEAP
end
@test abs(Float64(maxmem) - hint)/maxmem < 0.05

@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