当关联的 Javascript 对象在 V8 中垃圾回收时,如何释放包装的 C++ 对象?

How do you free a wrapped C++ object when associated Javascript object is garbage collected in V8?

提问人:postfuturist 提问时间:10/6/2008 最后编辑:postfuturist 更新时间:12/23/2009 访问量:5710

问:

V8 的文档解释了如何创建一个包装 C++ 对象的 Javascript 对象。Javascript 对象保留指向 C++ 对象实例的指针。我的问题是,假设您在堆上创建了 C++ 对象,当 gc 收集 Javascript 对象时,如何获得通知,以便释放堆分配的 C++ 对象?

JavaScript C++ v8

评论

0赞 Ron Burk 9/28/2020
提供的热链接(可能早已)失效。关于它可能包含的内容的一个合理的猜测是:v8.dev/docs/embed#templates

答:

0赞 Javier 10/7/2008 #1

通常,如果垃圾回收语言可以保存对语言引擎外部资源(文件、套接字或 C++ 对象)的引用,则应提供“关闭”方法以尽快释放该资源,而不必等到 GC 认为值得销毁对象。

如果你的 C++ 对象占用大量内存,而垃圾回收对象只是一个引用,情况会变得更糟:你可能分配了数千个对象,而 GC 只能看到几 KB 的小对象,不足以触发收集;而 C++ 方面正在与数十兆字节的陈旧对象作斗争。

评论

3赞 nalply 3/1/2010
这就是为什么有函数 V8::AdjustAmountOfExternalAllocatedMemory()...这样你就可以告诉 V8 你的物体饿了...... :-)
0赞 Thevs 10/7/2008 #2

在某个封闭的范围内(对象或函数)完成所有工作。 然后,您可以在超出范围时安全地删除 C++ 对象。GC 不检查指针是否存在指向对象。

23赞 Max Lybbert 10/7/2008 #3

诀窍是创建一个句柄(链接到 API 参考的第二个要点:“句柄不保留在堆栈上,只有在您专门删除它们时才会删除它们。...当您需要为多个函数调用保留对对象的引用时,或者当句柄生存期不对应于 C++ 范围时,请使用持久句柄。 当所有“常规”句柄都超出范围时,以及垃圾回收器即将删除对象时)。PersistentPersistentMakeWeak()Persistent::MakeWeak

方法签名为:Persistent::MakeWeak

void MakeWeak(void* parameters, WeakReferenceCallback callback);

其中定义为具有两个参数的指向函数的指针:WeakReferenceCallback

typedef void (*WeakReferenceCallback)(Persistent<Object> object,
                                      void* parameter);

这些可以在 v8.h 头文件中找到,该文件与 V8 一起作为公共 API 分发。

您可能希望传递给的函数清理对象参数,该参数在作为回调调用时将传递给它。可以忽略该参数(也可以指向包含需要清理的对象的 C++ 结构):MakeWeakPersistent<Object>void* parametervoid* parameter

void CleanupV8Point(Persistent<Object> object, void*)
{
    // do whatever cleanup on object that you're looking for
    object.destroyCppObjects();
}

Parameter<ObjectTemplate> my_obj(ObjectTemplate::New());

// when the Javascript part of my_obj is about to be collected
// we'll have V8 call CleanupV8Point(my_obj)
my_obj.MakeWeak(NULL, &CleanupV8Point);

评论

0赞 xaxxon 12/28/2015
如何为 Local<Object> 执行此操作?我正在尝试从我的构造函数FunctionTemplate中执行此操作。我想不出一种不会对我大喊大叫的语法。试。MakeWeak 但不存在,尝试了 Persistent::New,但它需要指向我的对象的指针,而我的编译器不允许我创建指向本地对象的指针。
0赞 Max Lybbert 12/29/2015
@xaxxon:我将是第一个承认我没有任何 V8 Javascript 引擎经验的人(我碰巧能够从六年前的文档中找到这个问题的答案)。我认为你的问题的答案是 developers.google.com/v8/embed?csw=1#dynamic 上的例子,但也有可能你有一个值得单独问的问题。
0赞 xaxxon 12/29/2015
谢谢。我最终弄清楚了。code.google.com/p/chromium/codesearch#chromium/src/v8/src/......从1400号线开始