|
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