侧边栏壁纸
  • 累计撰写 218 篇文章
  • 累计创建 59 个标签
  • 累计收到 5 条评论

NAPI 笔记 05:运行环境、调用请求 & 引用计数

barwe
2022-08-30 / 0 评论 / 0 点赞 / 1,210 阅读 / 2,775 字
温馨提示:
本文最后更新于 2023-06-07,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

class Env

https://github.com/nodejs/node-addon-api/blob/main/doc/env.md

模块运行的 JavaScript 环境,通常由 Node.js 或者 node-addon-api 底层创建并传递给开发者使用。

Env实例一般不需要我们手动创建,它作为初始化Addon实例时的第一个参数传递给构造函数:

class ExampleAddon : public Addon<ExampleAddon> {
    public:
    ExampleAddon(Env env, Object exports) { /* ... */ }
}

methods

指定环境中的 JavaScript 全局对象:

Object Env::Global() fconst;

指定环境中的 JavaScript undefined 对象:

Value Env::Undefined() const;

指定环境中的 JavaScript null 对象:

Value Env::Null() const;

指定环境中有尚未处理的异常(禁用 C++ 异常时):

bool Env::IsExceptionPending() const;

取出并清空指定环境中的异常:

Error Env::GetAndClearPendingException() const;

在指定环境中执行 JavaScript 代码块:

Value Env::RunScript(Napi::String script) const;
Value Env::RunScript(const char* script) const;
Value Env::RunScript(const std::string& script) const;

返回已经绑定到环境上的 Addon 实例:

template <typename T> T* Env::GetInstanceData() const;
// T 是自定义实现的 Addon 子类实例

将当前 addon 实例绑定的到指定环境上:SetInstanceData

class CleanupHook

当环境被创建时执行一系列钩子:

template <typename Hook>
CleanupHook<Hook> Env::AddCleanupHook(Hook hook);

template <typename Hook, typename Arg>
CleanupHook<Hook, Arg> AddCleanupHook(Hook hook, Arg* arg);

NAPI 维护了一个钩子栈,允许多次注册相同的钩子,最近注册的钩子会被最先执行。

提供了移除钩子的 API:

bool IsEmpty();
bool Remove(Env env);

class CallbackInfo

https://github.com/nodejs/node-addon-api/blob/main/doc/callbackinfo.md

包含与 JavaScript 调用 请求相关的数据,通常由 Node.js 或者 NAPI 底层创建。

CallbackInfo(napi_env env, napi_callback_info info);

methods:

  • Env CallbackInfo::Env() 创建调用请求时的运行环境
  • Value CallbackInfo::NewTarget()
  • bool CallbackInfo::IsContructCall() 是否是构造器函数调用
  • size_t CallbackInfo::Length() 传递给 CallbackInfo 对象的参数个数
  • const Value operator [](size_t index) 按0-索引访问参数
  • Value CallbackInfo::This() 在 JavaScript 中调用时的this
  • void* CallbackInfo::Data() 指向 JavaScript 中发起调用请求的回调函数的数据
  • void CallbackInfo::SetData(void* data)

class Reference

https://github.com/nodejs/node-addon-api/blob/main/doc/reference.md

Reference负责维护对Value对象的 引用计数,默认情况下变量持有对象的 弱引用,除非声明为其他引用类型。

对象的引用计数变为 0 不代表对象会被立即回收,只是说变量可以被回收了,具体的回收时间还得看 GC 啥时候有空。

Reference实例创建于静态空间之中,例如全局静态实例。如果想要在程序关闭期间仍然保留对象,以防止运行环境失效时重置引用计数,可以调用其SuppressDestruct()方法防止自己被解构。这个用法很奇怪,一般估计用不到。

直接或者间接继承这个类的子类有:ObjectWrap, ObjectReference, FunctionReference

部分方法:

  • Env Env() Reference 对象实例化时所处的运行环境
  • T Value() Reference 对象持有的值
  • bool IsEmpty() 持有的值是否为空
  • uint32_t Ref() 增加引用计数,返回计数
  • uint32_t Unref() 减少引用计数,返回计数
  • void Reset() 重置持有值为空
  • void Reset(const T& value, uint32_t refcount = 0) 重置持有值和计数

引用计数

引用计数 是 Java 进行垃圾回收的一个重要特性。从 JDK 1.2 之后,对象的引用被划分为 4 个级别。

Strong Reference

强引用 是最常见的引用,我们一般将一个对象赋值给一个变量,这个变量就是 强引用变量

一般对象存储在堆中,引用变量存储在栈上。

函数执行完成时,引用变量被释放,被引用对象的引用计数为0,等待 JVM 回收。

当一个对象存在强引用时,JVM 不会回收它,即使它没有被使用。

Soft Reference

在 Java 中 软引用 需要通过SoftReference<T>类来实现。

当内存足够时,软引用不会被回收;当内存紧张时,JVM 会自动回收软引用以获得资源。

JVM 优先回收长时间闲置不用的软引用对象,尽可能保留较新的软引用对象。

Weak Reference

在 Java 中 弱引用 需要通过WeakReference<T>类来实现。

软引用 的生存期更短,JVM 垃圾回收执行时总是会回收弱引用对象,而回收软引用还得看看空间够不够。

Phantom Reference

在 Java 中 虚引用 需要通过PhantomReference类来实现,且必须与ReferenceQueue关联。

虚引用不会决定对象的生命周期,一个对象仅持有虚引用,它和没有引用一样,随时可能被垃圾回收。

虚引用可以用于跟踪对象被回收的状态。

0

评论区