首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >蜘蛛猴与垃圾收集

蜘蛛猴与垃圾收集
EN

Stack Overflow用户
提问于 2012-03-07 10:19:53
回答 2查看 2.4K关注 0票数 3

我将蜘蛛侠嵌入到我的C++应用程序中。我需要在本机C++中实现一些通过jsval传递的定制Javascript函数。我需要保护jsval以防偶然垃圾收集。我这样做合适吗?

(1)在日常生活中:

代码语言:javascript
运行
复制
static jsval vp; // a STATIC variable, value unknown
JSBool init((JSContext *cx, uintN argc, jsval *vp) {
   JS_AddValueRoot(cx,  &vp);
}

(2)在一个实现Javascript函数setter()的c++函数中:

代码语言:javascript
运行
复制
JSBool setter(JSContext *cx, uintN argc, jsval *vp) {
   ...
  vp=...;// set to some JSObject and hopefully makes any previous JSObject available for gc

}

(3)在实现Javascript函数getter()的同一个编译单元中的第二个C++函数调用中:

代码语言:javascript
运行
复制
JSBool getter(JSContext *cx, uintN argc, jsval *vp) {
  jsval somethingelse = vp; //directly retrieve the static value stored by setter()
  ....
}

我的Javascript脚本使用如下函数调用:

代码语言:javascript
运行
复制
init();
setter(...);
some_other_function_call_that_causes_gc();
getter();
setter(...);
some_other_function_call_that_causes_gc();
getter();
....
some_other_function_call_that_causes_gc();
setter(...);
some_other_function_call_that_causes_gc();
getter();

请注意,我从不调用JS_RemoveRoot(),因为静态jsval是在两个函数调用之间传递的jsval的永久存储。而且,我一直在setter()中为gc根静态变量vp设置新值,假设jsval中存储的任何以前的JSObject都可用于垃圾收集。

这些创建gc根临时变量的正确方法可以跨函数调用传递吗?特别是,我的setter()取代以前的JSObject是使现有的JSObject对gc可用的适当方法(即没有内存泄漏/崩溃)。

编辑:我认为垃圾收集是一个问题的原因是:

https://developer.mozilla.org/En/SpiderMonkey/JSAPI_User_Guide

在JSAPI概念下,Javascript值:

jsval本身并不能保护它的引用不受垃圾收集器的影响。

https://developer.mozilla.org/en/SpiderMonkey_Garbage_Collection_Tips

示例3写着“根随”,并展示了如何将jsval分配给根用户。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-03-31 07:27:32

不需要为jsval这样的东西添加根。只需维护对脚本中值的引用即可。SpiderMonkey GC是基于参考计数的,因此只要在当前范围中引用它们,您的jsval就不会消失:

变量x= 5;

callNativeFun(x);

函数foo() {抛出true;}

打印(nativeFunRef());

//脚本在这里结束。X和FOO将被垃圾收集,callNativeFun和nativeFunRef js函数签名也会被垃圾收集。

在上面的代码示例中,x和foo都由全局对象引用。

只要在脚本中定义了jsval指针内容,它就永远不会到达GC。确保二进制代码在其生命周期结束后永远不会使用该值;也就是说,当您在脚本中使用它并调用delete或将其值设置为由作用域终止的值或代理定义的值时。如果您忽略了这些负面交互,您应该在jsval上设置GC根。

票数 0
EN

Stack Overflow用户

发布于 2014-03-03 02:07:10

指SpiderMonkey 17及以上

如果在使用GC时有可能触发GC,则应该保护jsval或任何其他GC设备。这是必需的,即使jsval指的是已经受到保护的存储。蜘蛛侠的GC是一个移动GC。

使用RootedValue保护基于堆栈的jsval和基于堆的jsvalHeap<JS::Value>

(jsvalJS::Value相同)。函数的参数使用Handle<JS::Value>MutableHandle<JS::Value>

以下是RootingAPI注释的摘录:

代码语言:javascript
运行
复制
 * A moving GC may change the physical location of GC allocated things, even
 * when they are rooted, updating all pointers to the thing to refer to its new
 * location. The GC must therefore know about all live pointers to a thing,
 * not just one of them, in order to behave correctly.
 *
 * For a code fragment such as:
 *
 * JSObject *obj = NewObject(cx);
 * DoSomething(cx);
 * ... = obj->lastProperty();
 *
 * If |DoSomething()| can trigger a GC, the stack location of |obj| must be
 * rooted to ensure that the GC does not move the JSObject referred to by
 * |obj| without updating |obj|'s location itself. This rooting must happen
 * regardless of whether there are other roots which ensure that the object
 * itself will not be collected.
 *
 * If |DoSomething()| cannot trigger a GC, and the same holds for all other
 * calls made between |obj|'s definitions and its last uses, then no rooting
 * is required.
 *
 * SpiderMonkey can trigger a GC at almost any time and in ways that are not
 * always clear. For example, the following innocuous-looking actions can
 * cause a GC: allocation of any new GC thing; JSObject::hasProperty;
 * JS_ReportError and friends; and ToNumber, among many others. The following
 * dangerous-looking actions cannot trigger a GC: js_malloc, cx->malloc_,
 * rt->malloc_, and friends and JS_ReportOutOfMemory.
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9599589

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档