Elide/ Architecture

Architecture · garbage collection

One managed heap across languages.

One heap across languages. Two collectors for different workloads: Serial keeps memory use low for CLI tools, desktop apps and low-traffic servers; G1 targets high throughput and short pauses for demanding servers.

Walkthrough

One managed heap across languages

Elide's JavaScript, TypeScript and Python objects share one managed heap with the engine's Kotlin and Java objects 1 2. Choose the collector when you build: Serial GC for a small memory footprint in CLI tools, desktop apps and low-traffic servers; G1 GC for high throughput and responsive servers 3 4.

CPython tracks references and collects cycles

CPython combines reference counting with cycle detection 6 7. CPython reclaims an object when its reference count reaches zero. The cyclic collector finds objects kept alive only by references to each other; it runs under the GIL or pauses free-threaded execution 8 9.

V8 manages each isolate’s heap

Each V8 isolate has its own heap 10. Orinoco pauses JavaScript to collect young objects with parallel scavenging; old-generation marking runs concurrently 11. Combining independently managed heaps requires lifetime coordination, such as scoped references or a bridge that detects cross-heap cycles 12 27.

Keep memory use low with Serial GC

Serial GC uses one collector thread and pauses application execution during collection 4. Young collections copy live objects into survivor space and promote older survivors. Full collections reclaim unused objects across both generations. Its low memory overhead makes it a strong fit for CLI tools, desktop apps and low-traffic servers 4.

Sustain server throughput with G1 GC

G1 GC targets high throughput and short pauses by dividing the heap into regions 14. Young collections move live objects during pauses; marking runs concurrently 15 16. Mixed collections reclaim selected old regions alongside young ones 17 18. G1 uses a pause-time goal to balance responsive requests with sustained server throughput 3 5 19.

One collector follows cross-language references

Truffle represents managed guest values as host objects 1 13. A JavaScript array can reference a Python dict holding a JavaScript function 2. One collector follows those references across languages and keeps objects reachable from the program's roots alive 1 5.

Set one heap reservation for every language

Elide accepts -Xmx and -XX:MaxHeapSize for every Truffle guest language 20. The Rust CLI parses the size into an isolate address-space reservation 21. Substrate VM sizes the managed heap within that reservation using its collector's memory policy 22 23.

Find what keeps objects alive across languages

Elide enables heap dumps, jvmstat and JFR at build time 24 26. VisualVM opens the heap dump to inspect managed objects and their references across the engine and guest runtimes 25 28.

Read the observability explainer
Host OS
Rust CLI
Rust · native
SVM heap
Truffle
instruments
Engine · Native Image
JS
TS
Py
Languages
Application
thread objects · reference countsT1GILa · strrc 1b · listrc 1c · noderc 1d · noderc 1cyclic collector idle
one managed heapyoung · edenyoung · survivorold generationprogramPcollectorGone threadSerial allocating
isolate · one heapyoung · fromyoung · tooldprogramJSmarkersMMisolate 2 own heap own collectorOrinoco allocating
one managed SVM heaparrayJSdictPyinstancehost JavarootsglobalsfunctionJSlistPyclosureJSarrayhost Javamarkone collector · shared reachability
regionsyoungyoungyoungfreeoldoldoldoldoldfreefreefreeprogramP1P2G1 threadsGGpause goalG1 allocating · young regionsgoal guides pause work · concurrent marking
app.jsapp.py-Xmx2g command lineRust CLI strips the flag parses the sizeisolate parameters reserved address spaceFFI
reserved bytes
Substrate VM heap collector sizes within it
app.jsapp.py-Xmx2g command lineRust CLI strips the flag parses the sizeisolate parameters reserved address spaceFFI
reserved bytes
Substrate VM heap collector sizes within it
Heap dumps · VisualVM
Managed objects and their references.

Cross-language cycles, one collector

A Python list and a JavaScript closure can keep each other alive. Once neither is reachable from the program's roots, one collector can reclaim the cycle 1 2. Choose low memory overhead with Serial or server throughput with G1; both collect the same cross-language object graph 3 4. GraalPy coordinates native extension objects separately through its reference-counting bridge and cycle detector 27.

Sources

  1. https://www.graalvm.org/truffle/javadoc/com/oracle/truffle/api/interop/InteropLibrary.html § class description — interop values use Java representations, including TruffleObject implementations and boxed primitive values. The shared-graph argument concerns managed objects and references; pointer interop and native storage have their own lifetime rules.
  2. https://www.graalvm.org/latest/reference-manual/polyglot-programming/ § introduction — "a host JVM-based language and a guest language can directly interoperate with each other and pass data back and forth in the same memory space."
  3. https://www.graalvm.org/latest/reference-manual/native-image/optimizations-and-performance/MemoryManagement/ § G1 Garbage Collector — Native Image selects G1 with --gc=G1. Oracle GraalVM provides G1 on Linux AMD64/AArch64; GraalVM 25.1 release notes § Native Image adds macOS AArch64 support in GraalVM 25.1.3. The versioned release note extends the platform list in the memory-management guide. § Native Memory distinguishes managed heap allocations from direct buffers and other native allocations.
  4. Native Image Memory Management § Serial Garbage Collector and G1 Garbage Collector — build-time options --gc=serial and --gc=G1 choose the collector. Serial uses a single-threaded, stop-and-copy design with young and old generations. Young collections copy survivors; full collections reclaim unused objects in both generations.
  5. https://docs.oracle.com/en/java/javase/21/gctuning/garbage-first-g1-garbage-collector1.html § Basic Concepts and Heap Layout — G1 is a generational, region-based collector with concurrent marking and stop-the-world evacuation. Its pause target guides collection work; it is a goal rather than a per-pause deadline. Native Image’s G1 overview (source 3) documents the same balance of latency and throughput.
  6. https://docs.python.org/3/glossary.html § reference count (Python 3.14.7) — "When the reference count of an object drops to zero, it is deallocated."
  7. https://docs.python.org/3/library/gc.html (Python 3.14.7) — "Since the collector supplements the reference counting already used in Python"; "The GC classifies objects into three generations depending on how many collection sweeps they have survived." https://docs.python.org/3/glossary.html § garbage collection — "reference counting and a cyclic garbage collector that is able to detect and break reference cycles."
  8. https://docs.python.org/3/glossary.html § global interpreter lock — "assure that only one thread executes Python bytecode at a time." https://peps.python.org/pep-0703/ § Garbage Collection (Cycle Collection) — "The CPython cycle garbage collector currently relies on the global interpreter lock to prevent other threads from accessing Python objects while the collector finds cycles."
  9. https://docs.python.org/3/howto/free-threading-python.html (Python 3.14.7) — "Starting with the 3.13 release, CPython has support for a build of Python called free threading where the global interpreter lock (GIL) is disabled." https://peps.python.org/pep-0703/ (Status: Final) — "this requires two stop-the-world pauses when running the garbage collector without the GIL"; "the garbage collector will only use a single generation".
  10. https://v8.dev/docs/embed § Hello world — "An isolate is a VM instance with its own heap."
  11. https://v8.dev/blog/trash-talk (Peter Marshall, 2019-01-03) § Generational layout — young generation ("nursery" and "intermediate") and old generation. § Minor GC (Scavenger) — semi-space design, parallel, stop-the-world. § Major GC — marking, sweeping (free-list), compaction. § Orinoco — "Concurrent marking happens entirely in the background while JavaScript is executing on the main thread"; incremental marking; parallel compaction and sweeping.
  12. https://www.graalvm.org/latest/reference-manual/embed-languages/ § Polyglot Isolates — separate host and guest collectors require scoped references to avoid cross-heap cycles. Scoped references provide one architecture for coordinating independent collectors. GraalPy’s native bridge (source 27) is a concrete cycle-handling example.
  13. https://www.graalvm.org/truffle/javadoc/com/oracle/truffle/api/TruffleLanguage.html § class description — a Truffle language is an abstract Java class the implementer subclasses; "A Truffle language implementation contains all the services a language should provide to make it composable with other languages."
  14. HotSpot G1 guide (source 5 URL) § Heap Layout — "G1 partitions the heap into a set of equally sized heap regions, each a contiguous range of virtual memory … A region is the unit of memory allocation and memory reclamation."
  15. Same § Garbage Collection Pauses and Collection Set — "G1 performs garbage collections and space reclamation in stop-the-world pauses. Live objects are typically copied from source regions to one or more destination regions"; "Objects of the young generation (eden and survivor regions) are copied into survivor or old regions, depending on their age."
  16. Same § Young-only phase — "Concurrent marking determines all currently reachable (live) objects in the old generation regions to be kept for the following space-reclamation phase. While collection marking hasn't completely finished, Normal young collections may occur." § Marking — Snapshot-At-The-Beginning (SATB).
  17. Same § Space-reclamation phase — "multiple young collections that in addition to young generation regions, also evacuate live objects of sets of old generation regions. These collections are also called Mixed collections."
  18. Same § Basic Concepts — "G1 reclaims space in the most efficient areas first (that is the areas that are mostly filled with garbage, therefore the name)."
  19. Native Image Memory Management (source 3 URL) § G1 Garbage Collector › Performance Tuning — -XX:MaxGCPauseMillis expresses a pause-time goal. G1 uses observed collection costs to choose pause work (source 5). These are Native Image collector options; Elide’s heap-reservation interface is documented in sources 20–22.
  20. crates/cli/src/lib.rs:1325-1333 (ReadyCli.max_heap_bytes; "SVM never sees these flags"), :1351-1360 (parse_max_heap_flag for -Xmx<size> and -XX:MaxHeapSize=<size>), :1364-1392 (extract_max_heap_bytes strips the flag before --, last wins), :1503-1506 (called before the CLI parser). Tests :1873-1898 use ["elide", "-Xmx4g", "run", "script.js"]. The flag is language-agnostic; it sizes the Elide isolate, not a spawned HotSpot.
  21. packages/entry/bin/main.rs:511-521 — isolate creation sets reserved_address_space_size from parsed -Xmx, otherwise DEFAULT_HEAP_RESERVATION_BYTES. This is an address-space reservation, not a direct assignment to Native Image’s MaxHeapSize runtime option.
  22. packages/entry/src/vm.rs:118-139 — on 64-bit targets, the default reservation is 31 GiB of virtual address space. The reservation bounds addressable heap space without committing that amount of physical memory; Native Image sizes the heap within it.
  23. Native Image Memory Management (source 3 URL) § Java Heap Size and G1 Overview — G1’s default maximum heap is 25% of physical memory. Native Image also provides explicit heap-size options. Elide’s reservation path is documented separately in sources 20–22.
  24. tools/settings.mts:85-89,1476 at revision da0fe256a53c4555aac3b0e764e9f757d4e8ebc6 — enabledMonitoring contains jfr, jvmstat and heapdump; the Native Image configuration passes this list to --enable-monitoring.
  25. project/docs/architecture/observability/story.md § Story — complementary views of guest execution and the Native Image runtime. Heap inspection here concerns managed representations and their references; guest source-level inspection uses Truffle tools.
  26. https://www.graalvm.org/latest/reference-manual/native-image/debugging-and-diagnostics/JFR/ § Include JFR Support — Native Image enables JFR at build time and supports recordings and custom events. This source establishes the recording capability named alongside heap inspection.
  27. https://github.com/oracle/graalpython/blob/master/docs/user/Embedding-Native-Extensions.md § Memory Management — GraalPy coordinates managed references with reference-counted native extension objects. Its bridge tracks cross-boundary references and detects cycles spanning managed and native objects. This mechanism is separate from collection within the managed heap.
  28. https://www.graalvm.org/latest/reference-manual/native-image/guides/create-heap-dump/ § Create a Heap Dump with VisualVM and Analyze a Heap Dump — enabling heapdump,jvmstat supports discovery and heap-dump inspection in VisualVM. Inspection covers managed object representations and reference paths.