跳到主要内容

初探 Nodejs 内存泄漏

· 阅读需 3 分钟
Hanasaki
阿巴阿巴阿巴

这两天吃饱撑着,在探究为什么我的 Node 程序 Heap Usage 一直居高不下,而且会越来越多。

如何调试 NodeJS 程序

在VSCode中可以直接调试,选择Debug,显示所有自动调试配置,选择要运行的命令,就进入了调试模式,侧栏会显示出调试的信息。可以捕获 Heap 快照,拿到 ChromeDevTool 里面导入分析。

用 Node 的 --inspect 参数搭配 Chrome 实时分析

运行以下命令,进入了调试模式

node --inspect serve.js

在 Chrome 中打开 chrome://inspect,就可以看到 Open dedicated DevTool for Node,点击进入 Node 调试工具,就可以开始分析了。

放大问题

很多时候,人工是难以准确排查出问题的,因为会有很多不可预料的误差,导致每次运行的结果数据不准。这时候,要放大问题,大量测试多次触发漏洞,就能很清楚的发现问题。

k6 对接口进行测试,运行下列测试程序 k6 run test.js

// test.js
import http from 'k6/http';

export let options = {
vus: 100,
duration: '20s',
};

export default function () {
let res = http.post("http://localhost:5000/monitor/start", JSON.stringify({ phone: Math.random()*100000 }), { headers: { 'Content-Type': 'application/json' } })

console.log(res.body);
}

通过对比前后的 Heap Size,确实管用,明显增加了将近 8MB。

接着调用了一下其他的接口,调用 processMap.clear() 把保存子进程的 processMap 清空。内存果然又降回去了,但并没有和最开始一样,而是稍稍高出了一点点。

得出结论,引用计数法回收垃圾是实实在在的,这个例子验证了它。但是仍然困扰我的是,Heap 里的 [compiled code] 这部分会一直增加,无法被回收,增加的量很小...

未解之谜:每次访问接口,即使是访问 / 路径,返回一段文本, [compiled code] 也会不断增加?