提问人:postfuturist 提问时间:10/6/2008 最后编辑:postfuturist 更新时间:12/23/2009 访问量:5710
当关联的 Javascript 对象在 V8 中垃圾回收时,如何释放包装的 C++ 对象?
How do you free a wrapped C++ object when associated Javascript object is garbage collected in V8?
问:
V8 的文档解释了如何创建一个包装 C++ 对象的 Javascript 对象。Javascript 对象保留指向 C++ 对象实例的指针。我的问题是,假设您在堆上创建了 C++ 对象,当 gc 收集 Javascript 对象时,如何获得通知,以便释放堆分配的 C++ 对象?
答:
通常,如果垃圾回收语言可以保存对语言引擎外部资源(文件、套接字或 C++ 对象)的引用,则应提供“关闭”方法以尽快释放该资源,而不必等到 GC 认为值得销毁对象。
如果你的 C++ 对象占用大量内存,而垃圾回收对象只是一个引用,情况会变得更糟:你可能分配了数千个对象,而 GC 只能看到几 KB 的小对象,不足以触发收集;而 C++ 方面正在与数十兆字节的陈旧对象作斗争。
评论
在某个封闭的范围内(对象或函数)完成所有工作。 然后,您可以在超出范围时安全地删除 C++ 对象。GC 不检查指针是否存在指向对象。
诀窍是创建一个句柄(链接到 API 参考的第二个要点:“句柄不保留在堆栈上,只有在您专门删除它们时才会删除它们。...当您需要为多个函数调用保留对对象的引用时,或者当句柄生存期不对应于 C++ 范围时,请使用持久句柄。 当所有“常规”句柄都超出范围时,以及垃圾回收器即将删除对象时)。Persistent
Persistent
MakeWeak()
Persistent::MakeWeak
方法签名为:Persistent::MakeWeak
void MakeWeak(void* parameters, WeakReferenceCallback callback);
其中定义为具有两个参数的指向函数的指针:WeakReferenceCallback
typedef void (*WeakReferenceCallback)(Persistent<Object> object,
void* parameter);
这些可以在 v8.h 头文件中找到,该文件与 V8 一起作为公共 API 分发。
您可能希望传递给的函数清理对象参数,该参数在作为回调调用时将传递给它。可以忽略该参数(也可以指向包含需要清理的对象的 C++ 结构):MakeWeak
Persistent<Object>
void* parameter
void* 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);
评论