对生命周期比原生方法长的对象的引用
🌐 References to objects with a lifespan longer than that of the native method
在某些情况下,插件需要能够创建和引用寿命超过单个本地方法调用的对象。例如,要创建一个构造函数并在后续请求中使用该构造函数来创建实例,就必须能够在许多不同的实例创建请求中引用该构造函数对象。使用前面章节中描述的作为 napi_value 返回的普通句柄是无法实现的。普通句柄的生命周期由作用域管理,并且所有作用域必须在本地方法结束之前关闭。
🌐 In some cases an addon will need to be able to create and reference objects
with a lifespan longer than that of a single native method invocation. For
example, to create a constructor and later use that constructor
in a request to creates instances, it must be possible to reference
the constructor object across many different instance creation requests. This
would not be possible with a normal handle returned as a napi_value as
described in the earlier section. The lifespan of a normal handle is
managed by scopes and all scopes must be closed before the end of a native
method.
Node-API 提供了创建对象持久引用的方法。每个持久引用都有一个关联的计数,值为 0 或更高。计数决定了引用是否会保持对应对象的存活。计数为 0 的引用不会阻止对象被回收,通常称为“弱引用”。任何大于 0 的计数都将阻止对象被回收。
🌐 Node-API provides methods to create persistent references to an object. Each persistent reference has an associated count with a value of 0 or higher. The count determines if the reference will keep the corresponding object live. References with a count of 0 do not prevent the object from being collected and are often called 'weak' references. Any count greater than 0 will prevent the object from being collected.
引用可以在创建时设置初始引用计数。然后可以通过 napi_reference_ref 和 napi_reference_unref 修改计数。如果在引用的计数为 0 时对象被回收,随后对与该引用相关联的对象调用 napi_get_reference_value 将返回 NULL 作为返回的 napi_value。尝试对已被回收的对象的引用调用 napi_reference_ref 会导致错误。
🌐 References can be created with an initial reference count. The count can
then be modified through napi_reference_ref and
napi_reference_unref. If an object is collected while the count
for a reference is 0, all subsequent calls to
get the object associated with the reference napi_get_reference_value
will return NULL for the returned napi_value. An attempt to call
napi_reference_ref for a reference whose object has been collected
results in an error.
一旦不再需要,必须删除引用。当引用被删除时,它将不再阻止相应的对象被回收。如果未删除持久引用,将导致“内存泄漏”,持久引用的本地内存和堆上的相应对象都会被永久保留。
🌐 References must be deleted once they are no longer required by the addon. When a reference is deleted, it will no longer prevent the corresponding object from being collected. Failure to delete a persistent reference results in a 'memory leak' with both the native memory for the persistent reference and the corresponding object on the heap being retained forever.
可以创建多个持久引用指向同一个对象,每个引用会根据其自身的计数决定是否保持对象的存活。对同一个对象的多个持久引用可能导致本地内存意外被保留。持久引用所对应的本地结构必须在被引用对象的终结器执行之前保持有效。如果为同一个对象创建新的持久引用,则该对象的终结器不会被执行,且早期持久引用所指向的本地内存不会被释放。可以通过在可能的情况下同时调用 napi_delete_reference 和 napi_reference_unref 来避免这种情况。
🌐 There can be multiple persistent references created which refer to the same
object, each of which will either keep the object live or not based on its
individual count. Multiple persistent references to the same object
can result in unexpectedly keeping alive native memory. The native structures
for a persistent reference must be kept alive until finalizers for the
referenced object are executed. If a new persistent reference is created
for the same object, the finalizers for that object will not be
run and the native memory pointed by the earlier persistent reference
will not be freed. This can be avoided by calling
napi_delete_reference in addition to napi_reference_unref when possible.