作者:elvinpeng,腾讯 WXG 前端开发工程师
Node.js 使用的是 V8 引擎,会自动进行垃圾回收(Garbage Collection,GC),因而写代码的时候不需要像 C/C++ 一样手动分配、释放内存空间,方便不少,不过仍然需要注意内存的使用,避免造成内存泄漏(Memory Leak)。
内存泄漏往往非常隐蔽,例如下面这段代码你能看出来是哪儿里有问题吗?
let theThing = null;
let replaceThing = function() {
const newThing = theThing;
const unused = function() {
if (newThing) console.log("hi");
};
// 不断修改引用
theThing = {
longStr: new Array(1e8).join("*"),
someMethod: function() {
console.log("a");
},
};
// 每次输出的值会越来越大
console.log(process.memoryUsage().heapUsed);
};
setInterval(replaceThing, 100);
如果可以的话,欢迎加入我们微信支付境外团队,一起不断追求卓越。如果暂时看不出来的话,一起来读读这篇文章吧。
文章的前半部分会先介绍一些理论知识,然后再举一个定位内存泄漏的例子,感兴趣的朋友可以直接先看看 这个例子。
整体结构
堆
-
指针空间(Old pointer space):存储的对象含有指向其它对象的指针。
数据空间(Old data space):存储的对象仅含有数据(不含指向其它对象的指针),例如从新生代移动过来的字符串等。
新生代(New Space/Young Generation):用来临时存储新对象,空间被等分为两份,整体较小,采用
Scavenge(Minor GC)
算法进行垃圾回收。老生代(Old Space/Old Generation):用来存储存活时间超过两个 Minor GC 时间的对象,采用
标记清除 & 整理(Mark-Sweep & Mark-Compact,Major GC)
算法进行垃圾回收,内部可再划分为两个空间:代码空间(Code Space):用于存放代码段,是唯一的可执行内存(不过过大的代码段也有可能存放在大对象空间)。
大对象空间(Large Object Space):用于存放超过其它空间对象限制(
Page::kMaxRegularHeapObjectSize
)的大对象(可以参考这个