当关联的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++对象?
技巧是创建一个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头文件中找到,该文件与作为公共API的v8一起分发。
您希望传递给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);
通常,如果垃圾收集的语言可以保存对语言引擎之外的资源(文件、套接字,或者在您的情况下是C++对象)的引用,那么您应该提供一个"关闭"方法来尽快释放该资源,而不必等到GC认为有必要销毁您的对象。
如果您的C++对象内存不足,而垃圾收集的对象只是一个引用,情况会更糟:您可能会分配数千个对象,而GC只看到几个KB的小对象,不足以触发收集;而C++方面正在与几十兆字节的过时对象作斗争。
在(对象或函数的)某个封闭范围内完成所有工作。然后,当您超出范围时,您可以安全地删除C++对象。GC不检查指针是否存在指向对象。
- COM :是否可以查看是否存在对我的某个 COM 对象的进程外引用?我可以释放它吗?
- 在C++中释放内存期间,迭代器与指针有何不同
- 错误:malloc:对象 0x7f9edf504080 的 *** 错误:未分配正在释放的指针
- 错误:"释放后使用包装器对象 (WRAPPER_ESCAPE)"
- 是否可以使用分配器对象来释放另一个分配器分配的内存?
- 释放 boost::singleton_pool 中的所有对象
- 完全释放静态对象内存
- 在Qt中执行完所有插槽后,如何释放对象
- 从函数内对象的向量中释放内存
- 如何修复对象在释放后可能修改的malloc错误
- 扩展auto_ptr以释放 C 样式对象
- OpenGL正在泄漏内存.哪个对象未释放
- C++ 删除对象不释放内存
- C :将内存从对象向量释放
- 创建对象的动态数组,删除对象并释放C++内存
- C++-如果抛出异常,则执行本地对象的释放
- 销毁对象和释放关联内存有什么区别
- 有效地从指向对象本身释放指针
- 从对象向量释放内存(不是对象的ptrs)
- WrapperPointer类和c++中堆栈分配对象的释放