Bun combines the high-performance generational garbage collector of JavaScriptCore (JSC) with the low-overhead native memory management of Zig and Rust. This page details the integration between these two worlds, focusing on how Bun manages heap objects, type-specific allocations via IsoSubspaces, and native memory using mimalloc and arena allocators.
Bun utilizes JavaScriptCore's generational, parallel, and concurrent garbage collector. The lifecycle of JavaScript objects is managed by the JSC::Heap, which is part of the JSC::VM.
The JSC::VM is initialized with specific heap parameters to balance performance and memory footprint. Bun's global object, Zig::GlobalObject, extends Bun::GlobalScope and integrates directly with the JSC VM lifecycle. It maintains a pointer to the m_bunVM for better cache locality.
Sources:
To maintain the generational invariant (old-generation objects must not point to young-generation objects without the collector's knowledge), Bun strictly employs JSC::WriteBarrier. Bun also maintains a WriteBarrierList to track specific references within the global object.
| Entity | Implementation | Purpose |
|---|---|---|
JSC::WriteBarrier<T> | BunObject.h | Standard member field protection for GC cells. |
visitChildren | BunObject.cpp | Traverses references during the marking phase. |
visitOutputConstraints | BunObject.cpp | Handles constraints for concurrent GC marking. |
Sources:
While JS objects live in the JSC heap, Bun's internal structures, buffers, and Zig-native data live in the native heap. Bun uses mimalloc, a performance-oriented allocator from Microsoft, as its primary native allocator scripts/build/deps/mimalloc.ts2-3
Bun configures mimalloc to act as a global malloc replacement on Linux scripts/build/deps/mimalloc.ts37 It is tuned for performance with several specific flags:
MI_SKIP_COLLECT_ON_EXIT: Skips the heap walk during process shutdown for faster exit scripts/build/deps/mimalloc.ts45MI_DEFAULT_ALLOW_THP: Disabled to save memory overhead (Transparent Huge Pages) on Linux scripts/build/deps/mimalloc.ts62MI_STATIC_LIB: Linked as a static library to avoid dynamic linking overhead scripts/build/deps/mimalloc.ts41MI_NO_PROCESS_DETACH: Skips mi_process_done as Bun is a static executable that exits via _exit scripts/build/deps/mimalloc.ts47-52MI_DEBUG: Set to level 3 in debug builds to enable heavy checks, guard bytes, and double-free detection scripts/build/deps/mimalloc.ts76-81Bun leverages SIMD instructions via the Google Highway library for high-performance string operations, such as escaping HTML or finding characters. These operations are runtime-dispatched based on CPU features (AVX2, SVE, etc.) to ensure baseline compatibility while maximizing performance on modern hardware.
Sources:
In the Rust core, Bun uses RawSlice<T> to manage non-owning borrowed slices where the backing storage outlives the holder. This is a byte-for-byte drop-in for raw pointers but provides a safer interface for re-borrowing as &[T] src/bun_core/lib.rs121-165
For testing purposes, Bun provides internal APIs to simulate memory-related conditions. The setSyntheticAllocationLimitForTesting function allows tests to enforce artificial memory limits src/js/internal-for-testing.ts141-145 Additionally, the crash_handler module provides functions like outOfMemory() to test Bun's behavior under extreme pressure src/js/internal-for-testing.ts99-106
Bun exposes memory usage statistics through process.memoryUsage() and specialized JSC internal helpers. In tests, xxHash3ForTesting and other bindings are used to verify the integrity of memory-intensive operations src/js/internal-for-testing.ts18-24
| Code Entity | File | Role |
|---|---|---|
RawSlice<T> | src/bun_core/lib.rs121 | Transparent wrapper for raw slice pointers. |
mimalloc | scripts/build/deps/mimalloc.ts17 | Global memory allocator configuration. |
Bun__setSyntheticAllocationLimitForTesting | src/js/internal-for-testing.ts143 | Zig binding to restrict allocations in tests. |
IndexOfCharImpl | src/jsc/bindings/highway_strings.cpp29 | SIMD-accelerated character search. |
Sources:
Refresh this wiki
This wiki was recently refreshed. Please wait 6 days to refresh again.