Skip to content

Commit 3d89d36

Browse files
committed
add ability to specify heap size hint as a percent
also fix overflowed subtraction with size hints < 250mb
1 parent fb2d946 commit 3d89d36

File tree

4 files changed

+42
-11
lines changed

4 files changed

+42
-11
lines changed

doc/man/julia.1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,8 @@ fallbacks to the latest compatible BugReporting.jl if not. For more information,
227227

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

233233
.TP
234234
--compile={yes*|no|all|min}

src/gc.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3938,14 +3938,22 @@ void jl_gc_init(void)
39383938
gc_num.max_pause = 0;
39393939
gc_num.max_memory = 0;
39403940

3941+
uint64_t mem_reserve = 250*1024*1024; // LLVM + other libraries need some amount of memory
3942+
uint64_t min_heap_size_hint = mem_reserve + 1*1024*1024;
3943+
uint64_t hint = jl_options.heap_size_hint;
39413944
#ifdef _P64
39423945
total_mem = uv_get_total_memory();
3943-
uint64_t constrained_mem = uv_get_constrained_memory();
3944-
if (constrained_mem > 0 && constrained_mem < total_mem)
3945-
jl_gc_set_max_memory(constrained_mem - 250*1024*1024); // LLVM + other libraries need some amount of memory
3946+
if (hint == 0) {
3947+
uint64_t constrained_mem = uv_get_constrained_memory();
3948+
if (constrained_mem > 0 && constrained_mem < total_mem)
3949+
hint = constrained_mem;
3950+
}
39463951
#endif
3947-
if (jl_options.heap_size_hint)
3948-
jl_gc_set_max_memory(jl_options.heap_size_hint - 250*1024*1024);
3952+
if (hint) {
3953+
if (hint < min_heap_size_hint)
3954+
hint = min_heap_size_hint;
3955+
jl_gc_set_max_memory(hint - mem_reserve);
3956+
}
39493957

39503958
t_start = jl_hrtime();
39513959
}

src/jloptions.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ static const char opts[] =
189189
" --bug-report=help.\n\n"
190190

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

195195
static const char opts_hidden[] =
@@ -821,14 +821,24 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp)
821821
case 'T':
822822
multiplier <<= 40;
823823
break;
824+
case '%':
825+
if (value > 100)
826+
jl_errorf("julia: invalid percentage specified in --heap-size-hint");
827+
uint64_t mem = uv_get_total_memory();
828+
uint64_t cmem = uv_get_constrained_memory();
829+
if (cmem > 0 && cmem < mem)
830+
mem = cmem;
831+
multiplier = mem/100;
832+
break;
824833
default:
834+
jl_errorf("julia: invalid unit specified in --heap-size-hint");
825835
break;
826836
}
827837
jl_options.heap_size_hint = (uint64_t)(value * multiplier);
828838
}
829839
}
830840
if (jl_options.heap_size_hint == 0)
831-
jl_errorf("julia: invalid argument to --heap-size-hint without memory size specified");
841+
jl_errorf("julia: invalid memory size specified in --heap-size-hint");
832842

833843
break;
834844
case opt_gc_threads:

test/cmdlineargs.jl

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,8 +1043,21 @@ end
10431043
@test lines[3] == "foo"
10441044
@test lines[4] == "bar"
10451045
end
1046-
#heap-size-hint, we reserve 250 MB for non GC memory (llvm, etc.)
1047-
@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)"
1046+
end
1047+
1048+
@testset "heap size hint" begin
1049+
#heap-size-hint, we reserve 250 MB for non GC memory (llvm, etc.)
1050+
@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)"
1051+
1052+
mem = ccall(:uv_get_total_memory, UInt64, ())
1053+
cmem = ccall(:uv_get_constrained_memory, UInt64, ())
1054+
if cmem > 0 && cmem < mem
1055+
mem = cmem
1056+
end
1057+
maxmem = parse(Int, readchomp(`$(Base.julia_cmd()) --startup-file=no --heap-size-hint=25% -e "println(@ccall jl_gc_get_max_memory()::UInt64)"`))
1058+
@test abs(maxmem - (0.25mem - 250*1024*1024))/maxmem < 0.01
1059+
1060+
@test parse(Int, readchomp(`$(Base.julia_cmd()) --startup-file=no --heap-size-hint=10M -e "println(@ccall jl_gc_get_max_memory()::UInt64)"`)) == "$(1*1024*1024)"
10481061
end
10491062

10501063
## `Main.main` entrypoint

0 commit comments

Comments
 (0)