返回

一文让你直观感受 GC 过程

见解分享

我们经常会说 JavaScript 是自动垃圾回收的,但是却从来没有真正地观察过 GC 的过程,也没有一个直观的感受。今天,我就通过一个 Node.js 的代码示例,带你直观地感受一下 Node.js 的 GC 过程。

首先,我们需要了解 GC 的基本原理。GC 的目的是回收不再被任何变量引用的对象,从而释放内存空间。在 JavaScript 中,当一个变量被声明时,它会占用一定的内存空间。当变量不再被任何引用指向时,它就会成为垃圾对象,可以被 GC 回收。

为了直观地展示 GC 的过程,我们编写了一个简单的 Node.js 代码:

const banana = { name: 'Banana' };

setTimeout(() => {
  banana = null;
}, 1000);

console.log(banana); // { name: 'Banana' }

在这段代码中,我们首先声明了一个对象 banana,并给它赋了一个属性 name。然后,我们使用 setTimeout() 函数创建一个延迟执行的函数,该函数将在 1 秒后将 banana 设为 null。最后,我们使用 console.log() 函数输出 banana 对象。

当我们运行这段代码时,我们会看到这样的输出:

{ name: 'Banana' }

这表明在 1 秒内,banana 对象仍然存在于内存中。但是,当 1 秒后延迟执行的函数被调用时,banana 对象就会被设置为 null。此时,banana 对象不再被任何变量引用,就成为了垃圾对象。GC 会在适当的时候回收这个垃圾对象,释放它所占用的内存空间。

为了更好地观察 GC 的过程,我们可以使用 Node.js 的 heapdump 模块来生成内存快照。我们可以使用以下命令来安装这个模块:

npm install --save heapdump

然后,我们可以在代码中添加以下代码来生成内存快照:

const heapdump = require('heapdump');

heapdump.writeSnapshot('snapshot.heapsnapshot');

这段代码会在当前时刻生成一个内存快照文件 snapshot.heapsnapshot。我们可以使用 Chrome DevTools 中的 Memory 工具来打开这个文件,并查看内存快照。

在内存快照中,我们可以看到 banana 对象在 1 秒内被创建并持有。当 1 秒后延迟执行的函数被调用时,banana 对象被设置为 null,并被标记为垃圾对象。GC 会在适当的时候回收这个垃圾对象,释放它所占用的内存空间。

通过这个简单的例子,你可以直观地感受到 GC 的工作过程。GC 是 JavaScript 语言中非常重要的一个机制,它可以帮助我们自动回收不再被使用的内存,从而避免内存泄漏和程序崩溃。