(1)在初始化程序中:
static jsval vp; // a STATIC variable, value unknown
JSBool init((JSContext *cx, uintN argc, jsval *vp) {
JS_AddValueRoot(cx, &vp);
}
(2)在一个实现JavaScript函数setter()的C++函数中:
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++函数调用:
JSBool getter(JSContext *cx, uintN argc, jsval *vp) {
jsval somethingelse = vp; //directly retrieve the static value stored by setter()
....
}
我的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 vp是在两个函数调用之间传递的my 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说“Root as you go”,并展示了一个jsval必须被分配为根的示例。