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

时间:2008-10-06 06:41:32

标签: javascript c++ v8

V8的文档解释了how to create a Javascript object that wraps a C++ object。 Javascript对象保持指向C ++对象实例的指针。我的问题是,假设您在堆上创建C ++对象,如何在gc收集Javascript对象时获得通知,以便可以释放堆分配的C ++对象?

3 个答案:

答案 0 :(得分:23)

诀窍是创建一个Persistent句柄(链接到API引用的第二个项目符号点:“Persistent句柄不会保留在堆栈上,只有在您专门删除它们时才会被删除。 ...当需要保持对一个对象的引用以进行多个函数调用时,或者当句柄生命周期与C ++范围不对应时,使用持久句柄。“),并在其上调用MakeWeak(),传递一个回调函数将执行必要的清理(“使用Persistent::MakeWeak可以使持久句柄变弱,以便在对对象的唯一引用来自弱持久句柄时从垃圾收集器触发回调。” - 是,当所有“常规”句柄超出范围并且垃圾收集器即将删除对象时。)

Persistent::MakeWeak方法签名是:

void MakeWeak(void* parameters, WeakReferenceCallback callback);

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

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

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

您希望传递给MakeWeak的函数清除Persistent<Object>对象参数,该参数在被称为回调时将传递给它。可以忽略void* parameter参数(或void* parameter可以指向包含需要清理的对象的C ++结构:

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);

答案 1 :(得分:0)

通常,如果垃圾收集语言可以保存对语言引擎之外的资源的引用(文件,套接字或在您的C ++对象中),那么您应该提供一种“关闭”方法来尽快释放该资源,不等到GC认为破坏你的物体是值得的。

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

答案 2 :(得分:0)

在一些封闭的范围内(对象或功能)完成所有工作。 当你超出范围时,你可以安全地删除C ++对象。 GC不检查指针是否存在尖头对象。