mirror of
https://github.com/oven-sh/bun
synced 2026-02-10 10:58:56 +00:00
experiment: tweak GC timings
This commit is contained in:
17
bench/snippets/read-file-large.mjs
Normal file
17
bench/snippets/read-file-large.mjs
Normal file
@@ -0,0 +1,17 @@
|
||||
import { readFile } from "node:fs/promises";
|
||||
|
||||
import { writeFileSync } from "node:fs";
|
||||
|
||||
(function () {
|
||||
writeFileSync("/tmp/bun-bench-large.text", Buffer.alloc(1024 * 1024 * 8, "abcdefg!"));
|
||||
})();
|
||||
if (globalThis.Bun) {
|
||||
Bun.gc(true);
|
||||
}
|
||||
|
||||
console.log("Before:", "RSS", (process.memoryUsage.rss() / 1024 / 1024) | 0, "MB");
|
||||
|
||||
for (let i = 0; i < 1024; i++) {
|
||||
await readFile("/tmp/bun-bench-large.text");
|
||||
}
|
||||
console.log("After:", "RSS", (process.memoryUsage.rss() / 1024 / 1024) | 0, "MB");
|
||||
@@ -218,6 +218,18 @@ extern "C" unsigned getJSCBytecodeCacheVersion()
|
||||
return getWebKitBytecodeCacheVersion();
|
||||
}
|
||||
|
||||
extern "C" void Bun__onEachMicrotaskTick(void* bun_vm, JSC::VM* vm);
|
||||
|
||||
static void defaultOnEachMicrotaskTick(JSC::VM& vm)
|
||||
{
|
||||
Bun__onEachMicrotaskTick(clientData(vm)->bunVM, &vm);
|
||||
}
|
||||
|
||||
static void defaultOnEachMicrotaskTickWithVM(void* bun_vm, JSC::VM& vm)
|
||||
{
|
||||
Bun__onEachMicrotaskTick(bun_vm, &vm);
|
||||
}
|
||||
|
||||
extern "C" void JSCInitialize(const char* envp[], size_t envc, void (*onCrash)(const char* ptr, size_t length), bool evalMode)
|
||||
{
|
||||
static bool has_loaded_jsc = false;
|
||||
@@ -799,6 +811,8 @@ static void checkIfNextTickWasCalledDuringMicrotask(JSC::VM& vm)
|
||||
globalObject->resetOnEachMicrotaskTick();
|
||||
queue->drain(vm, globalObject);
|
||||
}
|
||||
|
||||
Bun__onEachMicrotaskTick(globalObject->m_bunVM, &vm);
|
||||
}
|
||||
|
||||
static void cleanupAsyncHooksData(JSC::VM& vm)
|
||||
@@ -810,7 +824,8 @@ static void cleanupAsyncHooksData(JSC::VM& vm)
|
||||
vm.setOnEachMicrotaskTick(&checkIfNextTickWasCalledDuringMicrotask);
|
||||
checkIfNextTickWasCalledDuringMicrotask(vm);
|
||||
} else {
|
||||
vm.setOnEachMicrotaskTick(nullptr);
|
||||
vm.setOnEachMicrotaskTick(&defaultOnEachMicrotaskTick);
|
||||
Bun__onEachMicrotaskTick(globalObject->m_bunVM, &vm);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -856,7 +871,7 @@ void Zig::GlobalObject::resetOnEachMicrotaskTick()
|
||||
vm.setOnEachMicrotaskTick(&cleanupAsyncHooksData);
|
||||
} else {
|
||||
if (this->m_nextTickQueue) {
|
||||
vm.setOnEachMicrotaskTick(nullptr);
|
||||
vm.setOnEachMicrotaskTick(&defaultOnEachMicrotaskTick);
|
||||
} else {
|
||||
vm.setOnEachMicrotaskTick(&checkIfNextTickWasCalledDuringMicrotask);
|
||||
}
|
||||
@@ -923,8 +938,10 @@ extern "C" JSC__JSGlobalObject* Zig__GlobalObject__create(void* console_client,
|
||||
globalObject->resetOnEachMicrotaskTick();
|
||||
Bun::JSNextTickQueue* queue = jsCast<Bun::JSNextTickQueue*>(nextTickQueue);
|
||||
queue->drain(vm, globalObject);
|
||||
Bun__onEachMicrotaskTick(globalObject->m_bunVM, &vm);
|
||||
return;
|
||||
}
|
||||
Bun__onEachMicrotaskTick(globalObject->m_bunVM, &vm);
|
||||
});
|
||||
|
||||
if (executionContextId > -1) {
|
||||
|
||||
@@ -5709,7 +5709,7 @@ extern "C" JSC__JSValue JSC__JSValue__createRopeString(JSC__JSValue JSValue0, JS
|
||||
extern "C" size_t JSC__VM__blockBytesAllocated(JSC__VM* vm)
|
||||
{
|
||||
#if ENABLE(RESOURCE_USAGE)
|
||||
return vm->heap.blockBytesAllocated() + vm->heap.extraMemorySize();
|
||||
return vm->heap.blockBytesAllocated() + vm->heap.extraMemorySize() + vm->heap.externalMemorySize();
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
@@ -543,6 +543,9 @@ pub const GarbageCollectionController = struct {
|
||||
gc_repeating_timer_fast: bool = true,
|
||||
disabled: bool = false,
|
||||
|
||||
pub export fn Bun__onEachMicrotaskTick(vm: *VirtualMachine, jsc_vm: *JSC.VM) void {
|
||||
vm.gc_controller.processGCTimerWithHeapSize(jsc_vm, jsc_vm.blockBytesAllocated());
|
||||
}
|
||||
pub fn init(this: *GarbageCollectionController, vm: *VirtualMachine) void {
|
||||
const actual = uws.Loop.get();
|
||||
this.gc_timer = uws.Timer.createFallthrough(actual, this);
|
||||
@@ -612,7 +615,7 @@ pub const GarbageCollectionController = struct {
|
||||
pub fn onGCRepeatingTimer(timer: *uws.Timer) callconv(.C) void {
|
||||
var this = timer.as(*GarbageCollectionController);
|
||||
const prev_heap_size = this.gc_last_heap_size_on_repeating_timer;
|
||||
this.performGC();
|
||||
this.performGC(this.bunVM().jsc);
|
||||
this.gc_last_heap_size_on_repeating_timer = this.gc_last_heap_size;
|
||||
if (prev_heap_size == this.gc_last_heap_size_on_repeating_timer) {
|
||||
this.heap_size_didnt_change_for_repeating_timer_ticks_count +|= 1;
|
||||
@@ -652,7 +655,7 @@ pub const GarbageCollectionController = struct {
|
||||
this.updateGCRepeatTimer(.fast);
|
||||
|
||||
if (this_heap_size > prev * 2) {
|
||||
this.performGC();
|
||||
this.performGC(vm);
|
||||
} else {
|
||||
this.scheduleGCTimer();
|
||||
}
|
||||
@@ -661,17 +664,16 @@ pub const GarbageCollectionController = struct {
|
||||
.scheduled => {
|
||||
if (this_heap_size > prev * 2) {
|
||||
this.updateGCRepeatTimer(.fast);
|
||||
this.performGC();
|
||||
this.performGC(vm);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn performGC(this: *GarbageCollectionController) void {
|
||||
pub fn performGC(this: *GarbageCollectionController, js_vm: *JSC.VM) void {
|
||||
if (this.disabled) return;
|
||||
var vm = this.bunVM().jsc;
|
||||
vm.collectAsync();
|
||||
this.gc_last_heap_size = vm.blockBytesAllocated();
|
||||
js_vm.collectAsync();
|
||||
this.gc_last_heap_size = js_vm.blockBytesAllocated();
|
||||
}
|
||||
|
||||
pub const GCTimerState = enum {
|
||||
@@ -1618,7 +1620,7 @@ pub const EventLoop = struct {
|
||||
|
||||
/// Asynchronously run the garbage collector and track how much memory is now allocated
|
||||
pub fn performGC(this: *EventLoop) void {
|
||||
this.virtual_machine.gc_controller.performGC();
|
||||
this.virtual_machine.gc_controller.performGC(this.virtual_machine.jsc);
|
||||
}
|
||||
|
||||
pub fn wakeup(this: *EventLoop) void {
|
||||
|
||||
Reference in New Issue
Block a user