C++ 参数的V8内存管理';s返回值

C++ 参数的V8内存管理';s返回值,c++,garbage-collection,v8,C++,Garbage Collection,V8,我对V8如何管理其内存感到困惑 问题: 我知道V8基本上使用句柄来引用内存中的实际实例,并且使用HandleScope,可以自动轻松地管理所有本地句柄。但我无法理解为什么函数CallbackInfo不使用句柄来保留返回值: void MyMethod(const FunctionCallbackInfo<Value>& args) { Isolate* isolate = Isolate::GetCurrent(); HandleScope scope(is

我对V8如何管理其内存感到困惑

问题:

我知道V8基本上使用句柄来引用内存中的实际实例,并且使用HandleScope,可以自动轻松地管理所有本地句柄。但我无法理解为什么函数CallbackInfo不使用句柄来保留返回值:

void MyMethod(const FunctionCallbackInfo<Value>& args) 
{
    Isolate* isolate = Isolate::GetCurrent();
    HandleScope scope(isolate);

    cout<<"totally "<<args.Length()<<" arguments"<<endl;

    int result = AddOpeation(args[0]->Int32Value(), args[1]->Int32Value());
    char *s = new char [10];
    ZeroMemory(s, 10);
    _itoa_s(result, s, 9, 10);
    args.GetReturnValue().Set(String::NewFromUtf8(isolate, s)); // I'm confused by this line of code !!!
    delete [] s;
}
问题:

回到我的代码-函数MyMethod,因为ReturnValue::value_u不是句柄,一旦HandleScope被销毁,访问ReturnValue::value_u是否安全

我猜:

如果我创建了两个类的实例,如下所示:

HandleScope s0(...);
LocalHandle<FunctionCallbackInfo> h0 = ...;    
...
{
    HandleScope s1(...);
    LocalHandle<MyType> h1 = ...;
    h0.ptr = *h1; // Suppose ptr is a member field defined in FunctionCallbackInfo
}
HandleScope s0(…);
LocalHandle h0=。。。;
...
{
手镜s1(…);
localhandleh1=。。。;
h0.ptr=*h1;//假设ptr是函数callbackinfo中定义的成员字段
}
S1将在S0之前被销毁,因为S0仍然是活动的,h0也是,并且*h1是h0的成员字段,所以V8 GC不会清理*h1或h0.ptr引用的内存


我的猜测合理吗?

v8::HandleScope
将销毁作用域出口上的所有本地句柄。我想没有办法通知句柄范围哪个句柄是结果,不应该被销毁。但是
v8::EscapableHandleScope
允许执行以下操作:

void MyMethod(const FunctionCallbackInfo<Value>& args) 
{
    Isolate* isolate = Isolate::GetCurrent();
    EscapableHandleScope scope(isolate);

    int result = AddOpeation(args[0]->Int32Value(), args[1]->Int32Value());
    char s[10];
    _itoa_s(result, s, 9, 10);
    Local<String> result = String::NewFromUtf8(isolate, s);
    args.GetReturnValue().Set(scope.Escape(result));
}
void MyMethod(常量函数callbackinfo&args)
{
隔离*隔离=隔离::GetCurrent();
可卸手镜范围(隔离);
int result=addOpation(args[0]->Int32Value(),args[1]->Int32Value());
chars[10];
_itoa_s(结果,s,9,10);
本地结果=字符串::NewFromUtf8(隔离,s);
args.GetReturnValue().Set(scope.Escape(result));
}

请参阅V8指南部分的底部。

根据node.js官方网站中的示例代码,使用了HandleScope:
void方法(const FunctionCallbackInfo&args){Isolate*Isolate=Isolate::GetCurrent();HandleScope作用域(Isolate);args.GetReturnValue().Set(String::NewFromUtf8(Isolate,“world”);}
。我认为这个答案对于较新的V8是正确的。节点最有可能使用旧的V8版本,该版本没有
可转义HandleScope
  ...
  V8_INLINE void SetInternal(internal::Object* value) { *value_ = value; }
  V8_INLINE internal::Object* GetDefaultValue();
  V8_INLINE explicit ReturnValue(internal::Object** slot);
  internal::Object** value_;
HandleScope s0(...);
LocalHandle<FunctionCallbackInfo> h0 = ...;    
...
{
    HandleScope s1(...);
    LocalHandle<MyType> h1 = ...;
    h0.ptr = *h1; // Suppose ptr is a member field defined in FunctionCallbackInfo
}
void MyMethod(const FunctionCallbackInfo<Value>& args) 
{
    Isolate* isolate = Isolate::GetCurrent();
    EscapableHandleScope scope(isolate);

    int result = AddOpeation(args[0]->Int32Value(), args[1]->Int32Value());
    char s[10];
    _itoa_s(result, s, 9, 10);
    Local<String> result = String::NewFromUtf8(isolate, s);
    args.GetReturnValue().Set(scope.Escape(result));
}