A native Instance that is dropped without close() leaks all of its off-heap resources: the executable code region (~8 MB for a QuickJS-sized module), trampolines, jffi closures / Panama upcall stubs, ctx and args buffers, the tables and the linear memory. Nothing is registered with a java.lang.ref.Cleaner, so GC never reclaims them, unlike a bytecode instance where everything lives on the heap.
Measured with quickjs4j on Endive 1.1.0 (javy module, jffi runner, JDK 21): creating and dropping an engine without closing its instance grows RSS by ~30 MB per instance, linearly (1 GB after 20). With Instance.close() it saturates after JIT warm-up (~1 MB per instance residual over 50 instances, worth a look but minor).
quickjs4j had exactly this bug (Engine.close() never closed the Instance, which was harmless on bytecode) and other embedders will too. Suggested:
- register the native machine and memory with a
Cleaner as a fallback, so an unreachable instance releases its native resources on GC;
- document in the redline docs that native instances must be closed, since the bytecode fallback never required it.
🤖 Generated with Claude Code
A native
Instancethat is dropped withoutclose()leaks all of its off-heap resources: the executable code region (~8 MB for a QuickJS-sized module), trampolines, jffi closures / Panama upcall stubs, ctx and args buffers, the tables and the linear memory. Nothing is registered with ajava.lang.ref.Cleaner, so GC never reclaims them, unlike a bytecode instance where everything lives on the heap.Measured with quickjs4j on Endive 1.1.0 (javy module, jffi runner, JDK 21): creating and dropping an engine without closing its instance grows RSS by ~30 MB per instance, linearly (1 GB after 20). With
Instance.close()it saturates after JIT warm-up (~1 MB per instance residual over 50 instances, worth a look but minor).quickjs4j had exactly this bug (
Engine.close()never closed theInstance, which was harmless on bytecode) and other embedders will too. Suggested:Cleaneras a fallback, so an unreachable instance releases its native resources on GC;🤖 Generated with Claude Code