Skip to content

Commit 1c192fd

Browse files
authored
cap live_bytes to zero in a few places where GC intervals are computed (#170)
* cap live_bytes to zero in a few places where GC intervals are computed * mem / log(mem) for interval upper bound
1 parent 5f234f0 commit 1c192fd

File tree

1 file changed

+18
-7
lines changed

1 file changed

+18
-7
lines changed

src/gc.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#ifdef __GLIBC__
99
#include <malloc.h> // for malloc_trim
1010
#endif
11+
#include <math.h>
1112

1213
#ifdef __cplusplus
1314
extern "C" {
@@ -3669,29 +3670,39 @@ static int _jl_gc_collect(jl_ptls_t ptls, jl_gc_collection_t collection)
36693670
last_live_bytes = live_bytes;
36703671
live_bytes += -gc_num.freed + actual_allocd;
36713672

3673+
// XXX: we've observed that the `live_bytes` was negative in a few cases
3674+
// which is not expected. We should investigate this further, but let's just
3675+
// cap it to 0 for now.
3676+
int64_t live_bytes_for_interval_computation = live_bytes < 0 ? 0 : live_bytes;
3677+
36723678
if (collection == JL_GC_AUTO) {
36733679
//If we aren't freeing enough or are seeing lots and lots of pointers let it increase faster
36743680
if (not_freed_enough || large_frontier) {
3675-
int64_t tot = 2 * (live_bytes + actual_allocd) / 3;
3681+
int64_t tot = 2 * (live_bytes_for_interval_computation + actual_allocd) / 3;
36763682
if (gc_num.interval > tot) {
36773683
gc_num.interval = tot;
36783684
last_long_collect_interval = tot;
36793685
}
36803686
}
36813687
// If the current interval is larger than half the live data decrease the interval
36823688
else {
3683-
int64_t half = (live_bytes / 2);
3689+
int64_t half = (live_bytes_for_interval_computation / 2);
36843690
if (gc_num.interval > half)
36853691
gc_num.interval = half;
36863692
}
36873693
// But never go below default
3688-
if (gc_num.interval < default_collect_interval) gc_num.interval = default_collect_interval;
3694+
if (gc_num.interval < default_collect_interval)
3695+
gc_num.interval = default_collect_interval;
3696+
// And never go above the upper bound
3697+
const int64_t interval_upper_bound = (int64_t)((double)max_total_memory / log2((double)max_total_memory));
3698+
if (gc_num.interval > interval_upper_bound)
3699+
gc_num.interval = interval_upper_bound;
36893700
}
36903701

3691-
if (gc_num.interval + live_bytes > max_total_memory) {
3692-
if (live_bytes < max_total_memory) {
3693-
gc_num.interval = max_total_memory - live_bytes;
3694-
last_long_collect_interval = max_total_memory - live_bytes;
3702+
if (gc_num.interval + live_bytes_for_interval_computation > max_total_memory) {
3703+
if (live_bytes_for_interval_computation < max_total_memory) {
3704+
gc_num.interval = max_total_memory - live_bytes_for_interval_computation;
3705+
last_long_collect_interval = max_total_memory - live_bytes_for_interval_computation;
36953706
}
36963707
else {
36973708
// We can't stay under our goal so let's go back to

0 commit comments

Comments
 (0)