|
8 | 8 | #ifdef __GLIBC__ |
9 | 9 | #include <malloc.h> // for malloc_trim |
10 | 10 | #endif |
| 11 | +#include <math.h> |
11 | 12 |
|
12 | 13 | #ifdef __cplusplus |
13 | 14 | extern "C" { |
@@ -3669,29 +3670,39 @@ static int _jl_gc_collect(jl_ptls_t ptls, jl_gc_collection_t collection) |
3669 | 3670 | last_live_bytes = live_bytes; |
3670 | 3671 | live_bytes += -gc_num.freed + actual_allocd; |
3671 | 3672 |
|
| 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 | + |
3672 | 3678 | if (collection == JL_GC_AUTO) { |
3673 | 3679 | //If we aren't freeing enough or are seeing lots and lots of pointers let it increase faster |
3674 | 3680 | 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; |
3676 | 3682 | if (gc_num.interval > tot) { |
3677 | 3683 | gc_num.interval = tot; |
3678 | 3684 | last_long_collect_interval = tot; |
3679 | 3685 | } |
3680 | 3686 | } |
3681 | 3687 | // If the current interval is larger than half the live data decrease the interval |
3682 | 3688 | else { |
3683 | | - int64_t half = (live_bytes / 2); |
| 3689 | + int64_t half = (live_bytes_for_interval_computation / 2); |
3684 | 3690 | if (gc_num.interval > half) |
3685 | 3691 | gc_num.interval = half; |
3686 | 3692 | } |
3687 | 3693 | // 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; |
3689 | 3700 | } |
3690 | 3701 |
|
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; |
3695 | 3706 | } |
3696 | 3707 | else { |
3697 | 3708 | // We can't stay under our goal so let's go back to |
|
0 commit comments