首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >理解Node Addon (Node) HandleScope

理解Node Addon (Node) HandleScope
EN

Stack Overflow用户
提问于 2019-01-14 19:01:37
回答 3查看 2.3K关注 0票数 5

我很难理解如何正确使用HandleScopeEscapableHandleScope。例如,来自这个节点示例

代码语言:javascript
复制
MyObject::MyObject(const Napi::CallbackInfo& info) : Napi::ObjectWrap<MyObject>(info) {
  Napi::Env env = info.Env();
  Napi::HandleScope scope(env);

  this->val_ = info[0].As<Napi::Number>().DoubleValue();
};

在这种情况下,我们为什么需要创建一个新的HandleScope?来自另一个例子

代码语言:javascript
复制
Napi::Object CreateObject(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  Napi::Object obj = Napi::Object::New(env);
  obj.Set(Napi::String::New(env, "msg"), info[0].ToString());

  return obj;
}

为什么这里不需要它?

而且,我没有找到任何使用EscapableHandleScope的例子,这是什么时候需要的?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-01-15 19:09:14

有关HandleScopes是什么及其用途的说明,请参阅V8文档,例如,对于Local

句柄有两种类型:本地句柄和持久句柄。 本地句柄是重量轻和瞬态的,通常用于本地操作.它们由HandleScopes管理。这意味着当创建HandleScope时,它们必须存在于堆栈中,并且它们仅在创建过程中活动的HandleScope中有效。要将本地句柄传递给外部HandleScope,必须使用EscapableHandleScope及其Escape()方法。

对于HandleScope

控制许多本地句柄的堆栈分配类。在创建句柄作用域之后,将在该句柄范围内分配所有本地句柄,直到删除句柄作用域或创建另一个句柄范围为止。如果已经有一个句柄作用域并创建了一个新的句柄作用域,那么所有分配都将在新句柄作用域中进行,直到它被删除为止。在此之后,将再次在原始句柄范围中分配新句柄。 在删除了本地句柄的句柄作用域后,垃圾回收器将不再跟踪存储在句柄中的对象,并可能释放它。访问句柄作用域已被删除的句柄的行为未定义。

务实地:

  • 当从JavaScript调用到C++时,如果C++代码创建了任何Local<>,那么至少需要一个Local<>。通常正确的数字是一个HandleScope
  • 创建和销毁HandleScopes是有代价的,所以如果您有许多细粒度的HandleScopes,那么您就是在浪费时间。另一方面,一个HandleScope (根据设计,这就是它的目的!)保持包含在其中的句柄所指的所有对象都是活动的(在GC意义上),因此对于运行非常长的代码,或者使用多次迭代的循环,您可能需要引入短暂的HandleScopes,这样就可以释放完成任务的临时对象。
  • 如文档所述,如果要返回超出作用域生存期结束的对象,则需要一个EscapableHandleScope
票数 2
EN

Stack Overflow用户

发布于 2019-11-03 07:24:20

以下内容似乎适用于nan、nan和节点-addon:

句柄作用域是一种抽象,用于控制和修改在特定范围内创建的对象的生存期。通常,N值是在句柄作用域的上下文中创建的.当从JavaScript调用本机方法时,将存在一个默认句柄作用域。如果用户不显式创建新句柄作用域,则将在默认句柄范围中创建new值。对于本机方法执行之外的任何代码调用(例如,在libuv回调调用期间),模块是必需的,以便在调用任何可能导致创建JavaScript值的函数之前创建作用域。

来源:作用域

这意味着,在给出的示例中,由于两者都是直接从const Napi::CallbackInfo& info调用的,所以它们已经有了JS运行时提供的作用域--只有当您希望自己执行内存管理时,或者在您的代码独立于JS引擎执行的情况下(例如在计时器上,来自于JS代码以外的东西的回调,等等),创建作用域的附加调用才是必要的。

票数 4
EN

Stack Overflow用户

发布于 2020-01-20 07:59:54

为什么我们需要在代码片段中创建一个新的HandleScope?

实际上,我们可以选择在这里不创建一个新的HandleScope。Node.js中有一个外部作用域,它包含在此函数中创建的句柄。但是,在这个函数中创建的所有句柄都会比必要的长,并处理成本资源。

我们什么时候需要EscapableHandleScope?

当来自内部作用域的句柄需要超过该作用域的生存期时。例如,当返回函数中新创建的数据时。

参考文献

V8嵌入:https://v8.dev/docs/embed#handles-and-garbage-collection

节点-addon:management.md

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54187588

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档