调用处理程序数据的垃圾收集
garbage collection of call handler data
我试图向函数调用处理程序提供数据,但无法正确地进行垃圾收集。
如果我注释掉包含"tpl->SetCallHandler(callFn, external);
"的行,则调用ObjWeakCallback。不过,函数永远不会被收集(至少无论发生什么,都不会调用FnWeakCallback)。
请注意,静态数据不是一个选项,因为这需要为每个过程的多个隔离做好准备。isolate->setData
也不是一个选项。我是不是完全错过了什么?在v8::Function
中存储数据的正确方式是什么,有吗?
编辑:让我重新表述这个问题,以更好地描述我的意图。。。
我想创建一个函数模板(因为我需要将其用作JS端的构造函数)。我需要一些方法将void*发送到它的调用处理程序,但这些数据必须是垃圾可回收的。
到目前为止我一直在尝试的一些注意事项:
-
使用
Function::New(isolate, callHandler, External::New(isolate, data))
可以工作,但不提供JS端构造函数功能(无法为创建的对象设置InternalFieldCount) -
FunctionTemplate::New(isolate, callHandler, External::New(isolate, data))
提供了将数据传递给调用处理程序的能力,但从不进行垃圾收集(下面的工作示例) -
我尝试使用一个普通函数并返回一个新创建的
Object
,但随后以下假设new Fn() instanceof Fn
失败了
#include <v8.h>
#include <iostream>
// made static, just to simplify the example and prevent crashes
// the persistents would normally be wrapped inside a "baton" together with required data
v8::Persistent<v8::Value> p_obj;
v8::Persistent<v8::Value> p_fn;
void FnWeakCallback(const v8::WeakCallbackData<v8::Value, int>& data) {
int* number = data.GetParameter();
std::cout << "GC fn " << number << 'n';
delete number;
p_fn.Reset();
}
void ObjWeakCallback(const v8::WeakCallbackData<v8::Value, int>& data) {
int* number = data.GetParameter();
std::cout << "GC obj " << number << 'n';
delete number;
p_obj.Reset();
}
void callFn(const v8::FunctionCallbackInfo<v8::Value>& info) {
std::cout << "calledn";
}
void test(v8::Isolate* isolate) {
v8::HandleScope scope(isolate);
auto external = v8::External::New(isolate, new int{ 1 });
p_obj.Reset(isolate, external);
p_obj.SetWeak(new int{ 1 }, ObjWeakCallback);
auto tpl = v8::FunctionTemplate::New(isolate);
tpl->SetCallHandler(callFn, external); // <======
tpl->InstanceTemplate()->SetInternalFieldCount(1);
auto fn = tpl->GetFunction();
p_fn.Reset(isolate, fn);
p_fn.SetWeak(new int{ 2 }, FnWeakCallback);
}
int main() {
v8::V8::SetFlagsFromString("--expose-gc", 11);
auto isolate = v8::Isolate::GetCurrent();
v8::HandleScope handle_scope(isolate);
auto context = v8::Context::New(isolate);
context->Enter();
test(isolate);
isolate->RequestGarbageCollectionForTesting(v8::Isolate::kFullGarbageCollection);
context->Exit();
return 0;
}
现在我作弊了,并查看了代码
void GCController::CollectAll(const gin::Arguments& args) {
// In order to collect a DOM wrapper, two GC cycles are needed.
// In the first GC cycle, a weak callback of the DOM wrapper is called back
// and the weak callback disposes a persistent handle to the DOM wrapper.
// In the second GC cycle, the DOM wrapper is reclaimed.
// Given that two GC cycles are needed to collect one DOM wrapper,
// more than two GC cycles are needed to collect all DOM wrappers
// that are chained. Seven GC cycles look enough in most tests.
所以答案一定是:在第一次收集之后,你不会看到任何东西。
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 如何在信号处理程序和普通函数中对全局变量进行互斥读写操作
- 为什么我的 IExtractIcon 处理程序没有被调用?
- 在遍历处理程序的向量时注册和注销处理程序
- 有可能在信号处理程序中设置promise吗
- 在信号处理程序中捕获C++未处理的异常并恢复应用程序
- 通过安装信号处理程序关闭多线程应用程序
- QDateTime::toString() 在退出处理程序中使用时失败
- 如何在 WindowProc 处理程序中区分箭头键和数字键盘?
- async_write完成处理程序最早何时完成?
- C++事件系统 - 多态事件和事件处理程序
- 具有shared_ptr的处理程序中的分段错误
- 为什么我的信号处理程序只执行一次?
- GTK C++:找不到信号处理程序 您是否使用 -rdynamic 进行了编译?
- 如何使用从处理程序调度的最终回调将响应异步返回给调用方on_read?
- C++ 在信号处理程序后继续执行
- wxWidgets 拖放文件事件处理程序初始化问题(无效static_cast)
- 某些 boost::asio 异步函数是否将处理程序连接到操作,以便处理程序被触发一次?
- 没有信号处理程序的POSIX定时器的目的是什么?
- 处理程序的模块列表中有一个错误的模块"WebSocketModule"