用于定位 node 内存泄漏的工具常用的有:
• v8-profiler [1] • node-heapdump [2] • node-memwatch [3]
在演示 DEMO 之前可以了解点基本前置知识
关于 Node 的堆内存与堆外内存小记.
1. 受到 V8 GC 的主要是堆内存. 2. Node 中的内存并非都是通过 V8 来进行分配的, 可通过堆中的内存用量 (heapUsed) 总是小于进程常驻内存 (rss) 看出. 对于那些不是通过 V8 来分配内存的我们称为堆外内存, 比如 Buffer,Buffer 是基于 C++ 的不是 V8(从下面的 demo 中 rss 与 external 的值可以看出).external 代表 V8 管理的, 绑定到 JavaScript 的 C++ 对象的内存使用情况. 3. 因此表明堆外内存是可以突破内存限制问题.
使用 node-heapdump 排除内存泄漏的 DEMO
这里主要演示 node-heapdump, node-memwatch 很久没有维护了.
环境安装
• node.JS • node-gyp • Mac 下需要安装 xcode-select --install • Mac 下安装 xcode 后 sudo xcode-select --switch /Library/Developer/CommandLineTools/ • node-heapdump
代码
- const heapdump = require('heapdump')
- const http = require('http')
- const leakArray = []
- const leak = function() {
- leakArray.push(`leak: ${Math.random()}`)
- }
- http.createServer(function(req, res) {
- // 每次访问 node 服务. 都会往 leakArray 增加数据, 并且不会回收.
- leak()
- res.writeHead(200, {'Content-Type': 'text/plain'})
- res.end('hello node')
- }).listen(9999)
- console.log('server is running at: http:127.0.0.1:9999/')
然后我们通过在终通过 curl 不断访问服务器 curl http://127.0.0.1:9999 模拟用户访问, 这个时候 leakArray 数组不断增大, 并且不会被回收.
在 UNIX 平台上, 你可以向服务器进程通发送 SIGUSR2 信号强制快照.
$ kill -USR2 <pid>
Mac 下查看 pid
$ lsof -i tcp:9999
这个时候会在你的文件夹生成一个快照, 文件名格式默认为: heapdump- . .heapsnapshot.
由于 Node 是依赖 V8 引擎执行 JavaScript 的, Chrome 浏览器也是, 所以我们可以借助 Chrome 开发者工具中的 Memory 模块来分析这些 dump 文件. 首先打开 Chrome 的开发者工具, 切换到 Memory, 并依次加载 dump 文件.
关于 Summary 这个选项, 从图中可以看出它有 Constructor,Distance,Shallow Size,Retained Size 共 4 项. Constructor 这列是用类名对变量进行分组; Distance 表示和根对象的距离, 越小表示和根对象越近; Shallow Size 表示变量自身的大小, 不包含它引用的变量的大小; Retained Size 不仅包含自身的大小, 还包含了引用的变量的大小.
从图中可以看出,(string)那一行的 Shallow Size 和 Retained Size 都占据了 100% 的内存.
我们直接查看 distance(20)最远的那一行.
然后我们详情看下 leak().
当你再详细查看 leakArray 你就发现这里存储了大量的 leak 字符串, 它们一直未得到回收.
参考资料
• 深入浅出 node.JS
PS: 感兴趣的可以关注下公众号.
References
[1] v8-profiler: https://github.com/node-inspector/v8-profiler
[2] node-heapdump: https://github.com/bnoordhuis/node-heapdump
[3] node-memwatch: https://github.com/lloyd/node-memwatch
来源: http://www.tuicool.com/articles/neUJvuz