weak-napi: N-API Weak References

2.0.2 · active · verified Sun Apr 19

weak-napi is a Node.js module that provides functionality for creating weak references to JavaScript objects and registering callbacks that execute upon an object's garbage collection. It exposes the underlying V8 engine's GC tracking features, which are otherwise inaccessible from JavaScript. The current stable version is 2.0.2, with a release cadence primarily focused on N-API compatibility and stability. A key differentiator from its predecessor, `node-weak`, is its utilization of N-API, eliminating the need for recompilation across different Node.js versions and improving the robustness of GC callbacks to prevent crashes. It requires Node.js 6 or newer due to its reliance on Proxy objects for comprehensive property handling, and notably does not support the `isNearDeath()` API. This module is commonly employed for debugging memory leaks and understanding the lifecycle of objects within Node.js applications.

Common errors

Warnings

Install

Imports

Quickstart

This example demonstrates how to create a weak reference to an object and register a callback function to be executed when the object is garbage collected. It highlights best practices for callback placement and the process of dereferencing the original object. Due to the non-deterministic nature of garbage collection, the callback's execution time is not guaranteed without explicitly exposing V8's GC via Node.js `--expose-gc` flag.

var weak = require('weak-napi');

// We will monitor this object and invoke 'cleanup' after it's garbage collected
let obj = {
    id: 'my-object',
    data: Array(1000).fill('some data string') // Make it large enough to be GC'd
};

// Define the cleanup callback at a high scope to avoid strong references
function cleanupCallback() {
  console.log('"obj" with ID ' + this.id + ' has been garbage collected!');
}

// Create a weak reference to obj with the cleanup callback
// Note: `this` inside the callback refers to the EventEmitter instance returned by `weak()`.
const ref = weak(obj, cleanupCallback);
ref.id = obj.id; // Store ID on the ref for logging in callback

console.log('Weak reference created. Initial obj.id:', obj.id);

// Dereference the object to allow it to be garbage collected
obj = null;

console.log('Original object reference cleared. Waiting for GC...');

// In a real scenario, you'd let your application run.
// For demonstration, we might try to force GC, but it's not reliable or recommended.
// Global.gc is usually not available unless explicitly enabled with --expose-gc.
// If process.env.EXPOSE_GC is set, you can try to call it:
if (typeof global.gc === 'function') {
  console.log('Attempting to force garbage collection...');
  global.gc();
  global.gc(); // Call twice for better chances
} else {
  console.log('Run Node.js with --expose-gc flag to see immediate callback execution via global.gc().');
  console.log('Otherwise, the callback will eventually fire when V8 decides to run GC naturally.');
}

// Keep the process alive for a bit to allow GC to run naturally
setTimeout(() => {
  console.log('Process ending. If GC ran, you should have seen the callback message.');
}, 500);

view raw JSON →