javascript - 如何在 Spidermonkey 中创建、处理和销毁 JS::Heap<T> 对象?

标签 javascript memory-management garbage-collection spidermonkey

使用 Spidermonkey 24、38、45

Spidermonkey documentation说:“堆上的 GC 事物指针必须包装在 JS::Heap 中。唯一的异常(exception)是如果它们作为根添加到 JS_AddRoot() 函数或 JS::PersistentRooted 类中,但是不要'除非确实有必要,否则不要这样做。JS::Heap 指针也必须继续以正常方式进行跟踪,这里不做介绍。”

在这种情况下,跟踪到底意味着什么?以下代码是否遗漏了什么?

struct Foo
{
   Foo(JS::HandleObject bar) : _bar(bar) {}  // Does that root bar?
   ~Foo() {_bar = nullptr;}                  // Does that release memory?

   JS::Heap<JSObject*>  _bar;
};

Foo *create(JSContext *jscontext, JSObject *parent)
{
   JS::RootedObject bar(jscontext, JS_NewObject(jscontext, &SOME_CLASS, NULL, parent));
   return new Foo(bar);
}

我需要添加“跟踪”吗?当 bar 对象存储在 Foo 中时,我是否需要 root 对象?我是否应该使用 JS_AddRoot() 函数而不是使用堆来生成根栏?

最佳答案

JS::Heap<T>用于驻留在堆上的数据结构。跟踪确实是一个要求。没有它,GC 可能会确定您的对象无法访问或重新定位它而不更新您的 JS::Heap<T>处理。

在 spidermonkey 中追踪对象很简单。您需要使用 JS_AddExtraGCRootsTracer(JSRuntime* rt, JSTraceDataOp traceOp, void* data) 请求额外的 GC root tracer . JSTraceDataOp 是一个带有接口(interface) 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 在堆栈上 Root 酒吧 Foo* create . Heap<T>句柄不是根 - 这就是必须追踪它们的原因。一旦create返回时,对象不再有根。

  ~Foo() {_bar = nullptr;}                  // Does that release memory?

没有。 _bar只是 JS::Heap<T> 的一个实例处理。它指向的东西将在后续循环中被垃圾收集。

关于javascript - 如何在 Spidermonkey 中创建、处理和销毁 JS::Heap<T> 对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27393732/

相关文章:

javascript - 使用 Javascript 开始和停止重新加载页面

javascript - 使用 Vuejs 构建表单。将数据从 child 传递给 parent

java - 我应该在使用后重置 Java 堆空间最大值吗?

c++ - 在构造期间抛出 bad_alloc 时如何实现正确的堆栈展开和 raii

javascript - 以 http 格式放置诺基亚 map 的搜索 api?

javascript - 无法显示 Highchart

c++ - 无法在 C++ 中为 char* 分配内存

python - 从列表中删除元素后释放内存

.net - SqlCommand.Dispose 是否关闭连接?

java - Tomcat7 - 超出 GC 开销限制