SpiderMonkey Garbage Collection
Garbage Collection
JavaScript code implicitly allocates memory for objects, strings, variables, and so on.
Garbage collection is the process by which the JavaScript engine detects when those pieces of memory are no longer reachable.
The application must be very careful to ensure that any values it needs are GC-reachable.
Any object you leave lying around will be destroyed if you don't tell the JSAPI you're still using it.
The application should take steps to reduce the performance impact of garbage collection.
Keeping objects alive
If you just need the value to remain reachable for the duration of a
JSNative
call, store it in*rval
or an element of theargv
array. The values stored in those locations are always reachable.If a custom object needs certain values to remain in memory, just store the values in
properties
of the object.If a
function
creates new objects, strings, or numbers, it can useJS_EnterLocalRootScope
andJS_LeaveLocalRootScope
to keep those values alive for the duration of the function.To keep a value alive permanently, store it in a
GC root
. (JS_Add*Root
)
GC thing pointer
Refer to memory allocated and managed by the SpiderMonkey garbage collector.
JS::Value
JSObject*
JSString*
JSScript*
jsid
GC things on the stack
GC thing pointers that are parameters to a function must be wrapped in
JS::Handle<T>
A JS::Handle is a reference to a
JS::Rooted<T>
All
JS::Handle<T>
are created implicitly by referencing aJS::Rooted<T>
It is not valid to create a
JS::Handle<T>
manuallyJS::Handle
is immutable: it can only ever refer to theJS::Rooted<T>
that it was created forUse
JS::Handle<T>
for all function parameters taking GC thing pointers (except out-parameters)All GC thing pointers used as an out-parameter must be wrapped in a
JS::MutableHandle<T>
.
GC things on the heap
Must be wrapped in a
JS::Heap<T>
The only exception to this is if they are added as roots with the
JS_Add<T>Root
functions orJS::PersistentRooted
class, but don't do this unless it's really necessary.JS::Heap<T>
doesn't require aJSContext*
, and can be constructed with or without an initial value parameter.
Summary
Use
JS::Rooted<T>
for local variables on the stack.Use
JS::Handle<T>
for function parameters.Use
JS::MutableHandle<T>
for function out-parameters.Use an implicit cast from
JS::Rooted<T>
to get aJS::Handle<T>
.Use an explicit address-of-operator on
JS::Rooted<T>
to get aJS::MutableHandle<T>
.Return raw pointers from functions.
Use
JS::Rooted<T>
fields when possible for aggregates, otherwise use anAutoRooter
.Use
JS::Heap<T>
members for heap data.Do not use
JS::Rooted<T>
,JS::Handle<T>
orJS::MutableHandle<T>
on the heap.Do not use
JS::Rooted<T>
for function parameters.Use
JS::PersistentRooted<T>
for things that are alive until the process exits.
Last updated
Was this helpful?