Node.js排除内存泄漏演示

用于定位node内存泄漏的工具经常使用的有:javascript

在演示DEMO以前能够了解点基本前置知识

关于Node的堆内存与堆外内存小记。java

  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

环境安装

  • 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数组不断增大,而且不会被回收。git

在UNIX平台上,你能够向服务器进程通发送SIGUSR2信号强制快照。github

 $ kill -USR2 <pid>
复制代码

mac下查看pidshell

$ lsof -i tcp:9999
复制代码

这个时候会在你的文件夹生成一个快照,文件名格式默认为:heapdump-..heapsnapshot。数组

因为Node是依赖V8引擎执行JavaScript的,Chrome浏览器也是,因此咱们能够借助Chrome开发者工具中的Memory模块来分析这些dump文件。首先打开Chrome的开发者工具,切换到Memory,并依次加载dump文件。xcode

关于Summary这个选项,从图中能够看出它有Constructor、Distance、Shallow Size、Retained Size共4项。Constructor这列是用类名对变量进行分组;Distance表示和根对象的距离,越小表示和根对象越近;Shallow Size表示变量自身的大小,不包含它引用的变量的大小;Retained Size不只包含自身的大小,还包含了引用的变量的大小。浏览器

从图中能够看出,(string)那一行的Shallow Size和Retained Size都占据了100%的内存。bash

咱们直接查看distance(20)最远的那一行。

而后咱们详情看下leak()。

当你再详细查看leakArray你就发现这里存储了大量的leak字符串,它们一直未获得回收。

参考资料

  • 深刻浅出node.js

PS: 感兴趣的能够关注下公众号。

相关文章
相关标签/搜索