📜  Deno 内存使用 (1)

📅  最后修改于: 2023-12-03 14:40:42.389000             🧑  作者: Mango

Deno 内存使用

Deno 是一个安全的 TypeScript / JavaScript 运行时,使用 V8 引擎,由 Ryan Dahl(Node.js 的原始创建者)开发。Deno 中有多个内存使用方面需要考虑,本文将介绍一些使用 Deno 时需要知道的内存使用方面的知识。

垃圾回收

Deno 使用 V8 引擎作为其 JavaScript 执行引擎,V8 引擎实现了内存管理和垃圾回收(Garbage Collection)。V8 引擎使用标记清除算法(Mark-Sweep Algorithm)作为其垃圾回收方式。该算法分两个步骤,首先标记所有从根对象可达的对象,然后扫描整个堆并清楚未标记的对象。Denno运行时确保 V8 引擎的垃圾回收周期为 1-2 ms,这意味着在这个时间段内,V8 引擎会停止所有 JavaScript 代码来进行垃圾回收。

内存管理

在 Deno 中,内存管理问题通常由 V8 引擎处理。但是,Deno 运行时本身也会过滤掉内存泄漏,同时,Deno 运行时还附带了一些功能,以检测内存限制并让用户可以以编程方式限制内存使用。

--max-memory flag

Deno 运行时可以通过设置 --max-memory 标志来强制限制最大内存使用量。例如,以下语句将限制最大内存使用量为 128MB:

deno run --allow-read --allow-net --max-memory=128 src/index.ts
Deno.memoryUsage()

Deno 运行时还提供了 Deno.memoryUsage() 函数,该函数可以访问当前脚本使用的内存的一些信息,主要包括:

  • heapTotal:已分配的堆的总大小
  • heapUsed:已用的堆的大小
  • external:代表 V8 引擎管理的 JavaScript 对象绑定到 C + + 对象(例如 ArrayBuffer)的总大小

这里是一个展示如何使用 Deno.memoryUsage() 的示例:

console.log(Deno.memoryUsage().heapUsed);

输出将是一个整数,表示当前使用了多少内存(以字节为单位)。

FinalizationRegistry 和 WeakRef

Deno 运行时还提供了 FinalizationRegistry 和 WeakRef API,这些 API 可以帮助开发人员更好地处理对象的生命周期和内存使用。为了更好地理解这些 API,让我们看一个具体的示例:

// 引入 FinalizationRegistry 类
const registry = new FinalizationRegistry((value: Buffer) => {
  console.log(`${value} 这个对象被回收了`);
});

// 创建基于 ArrayBuffer 的数据结构
const buffer = new ArrayBuffer(1024);

// 将 ArrayBuffer 注册到 FinalizationRegistry,以便在重用之前通知开发人员
registry.register(buffer, buffer);

// 创建 WeakRef 对象,WeakRef 无法控制其引用对象,一旦对象被释放了,WeakRef 引用将被置为 null
const weakRef = new WeakRef(buffer);

// 在其他地方使用 WeakRef 引用这个对象,但要注意,只要 WeakRef 引用的对象不存在强引用时,就会变为 null
setTimeout(() => {
  if (weakRef.deref() === null) {
    console.log(`ArrayBuffer 已被回收`);
  } else {
    console.log(`ArrayBuffer 还在使用中`);
  }
}, 5000);

在上面的示例代码中,我们使用了 FinalizationRegistry 和 WeakRef 来帮助我们控制 ArrayBuffer 对象的生命周期,并且更好地管理内存的使用。

结论

在使用 Deno 运行时创建应用程序时,除了了解其内存使用方面的知识外,还需要根据需要调整其配置,以避免内存使用方面的问题,最好采用上述 API 和标志来确定程序的最大内存使用量,并且注意在使用数据缓存或类似内存密集型功能时,使用 FinalizationRegistry 和 WeakRef API 的方式来管理内存。