JS::Heap<T>
用于驻留在堆上的数据结构。追踪确实是一个要求。如果没有它,GC 可能会确定您的对象无法访问,或者在不更新您的对象的情况下重新定位它JS::Heap<T>
handle.
在 Spidermonkey 中追踪物体很简单。您需要使用以下命令请求额外的 GC 根跟踪器JS_AddExtraGCRootsTracer(JSRuntime* rt, JSTraceDataOp traceOp, void* data)
。 JSTraceDataOp 是一个带有接口的函数指针void traceOp(JSTracer* trc, void* data)
。在您的函数中,您必须调用各种JS_Call<T>Tracer
(定义于Tracer.h) 传递跟踪器和您的对象的方法。此外,您应该致电JS_TraceChildren
有必要的。
使用您的示例,添加跟踪器可能如下所示。
Foo* ref = create(cx, nullptr);
void trace_foos(JSTracer* tracer, void* data) {
JS_CallHeapObjectTracer(tracer, &(ref->_bar), "foo");
}
JS_AddExtraGCRootsTracer(rt, trace_foos, nullptr);
每当 GC 运行时,您的跟踪回调就会运行,您应该遍历对象图并跟踪 GC 的情况。
至于您评论中的问题——
Foo(JS::HandleObject bar) : _bar(bar) {} // Does that root bar?
bar
已经在堆栈上扎根了JS::RootedObject
bar in Foo* create
. Heap<T>
句柄不是根——这就是为什么必须追踪它们。立刻create
返回时,该对象不再有根。
~Foo() {_bar = nullptr;} // Does that release memory?
No. _bar
只是一个例子JS::Heap<T>
处理。它指向的东西将在后续循环中被垃圾收集。