aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar cirospaciari <ciro.spaciari@gmail.com> 2023-09-20 18:27:05 -0300
committerGravatar Ciro Spaciari <ciro.spaciari@gmail.com> 2023-09-20 23:42:14 -0300
commit8cac7ac32dd6d76327c5043a7a7a6b93d8c887ea (patch)
tree9ee580b01bcc05f49955f11053c3eea85eda6b13
parentb65862e23b255d2ebf6df8cd32481e5162c7f978 (diff)
downloadbun-8cac7ac32dd6d76327c5043a7a7a6b93d8c887ea.tar.gz
bun-8cac7ac32dd6d76327c5043a7a7a6b93d8c887ea.tar.zst
bun-8cac7ac32dd6d76327c5043a7a7a6b93d8c887ea.zip
aggressive GC using threshold
-rw-r--r--src/bun.js/event_loop.zig24
1 files changed, 22 insertions, 2 deletions
diff --git a/src/bun.js/event_loop.zig b/src/bun.js/event_loop.zig
index 7f175a1a1..2820869a4 100644
--- a/src/bun.js/event_loop.zig
+++ b/src/bun.js/event_loop.zig
@@ -445,10 +445,15 @@ pub const ConcurrentTask = struct {
const AsyncIO = @import("root").bun.AsyncIO;
+/// Minumum threadshold until we run GC aggressively
+const MINUMUM_HEAP_SIZE_THRESHOLD = 64 * 1024 * 1024;
+const MAXIMUM_HEAP_SIZE_THRESHOLD = std.math.maxInt(usize) / 2 - 1;
+
// This type must be unique per JavaScript thread
pub const GarbageCollectionController = struct {
gc_timer: *uws.Timer = undefined,
gc_last_heap_size: usize = 0,
+ gc_heap_size_threshold: usize = MINUMUM_HEAP_SIZE_THRESHOLD,
gc_last_heap_size_on_repeating_timer: usize = 0,
heap_size_didnt_change_for_repeating_timer_ticks_count: u8 = 0,
gc_timer_state: GCTimerState = GCTimerState.pending,
@@ -577,8 +582,23 @@ pub const GarbageCollectionController = struct {
pub fn performGC(this: *GarbageCollectionController) void {
if (this.disabled) return;
var vm = this.bunVM().global.vm();
- vm.collectAsync();
- this.gc_last_heap_size = vm.blockBytesAllocated();
+ if (this.gc_last_heap_size >= this.gc_heap_size_threshold and this.gc_last_heap_size < MAXIMUM_HEAP_SIZE_THRESHOLD) {
+ // agressive GC
+ _ = vm.runGC(true);
+
+ this.gc_last_heap_size = vm.blockBytesAllocated();
+ if (this.gc_last_heap_size <= MAXIMUM_HEAP_SIZE_THRESHOLD) {
+ // avoid GCing again if the memory is still high creating a new threshold
+ this.gc_heap_size_threshold = @max(MINUMUM_HEAP_SIZE_THRESHOLD, this.gc_last_heap_size * 2);
+ } else {
+ // this shows that memory is very high, so and we will avoid GCing again because of performance reasons
+ // at this point JSC should be able to control memory better than we can
+ this.gc_heap_size_threshold = MAXIMUM_HEAP_SIZE_THRESHOLD;
+ }
+ } else {
+ vm.collectAsync();
+ this.gc_last_heap_size = vm.blockBytesAllocated();
+ }
}
pub const GCTimerState = enum {