nodejs 内存泄漏

memwatch

test.js

var http = require('http');

var server = http.createServer(function (req, res) {
     for (var i=0; i<1000; i++) {
            server.on('request', function leakyfunc() {});
             }

              res.end('Hello World\n');
}).listen(1337, '127.0.0.1');

server.setMaxListeners(0);
console.log('Server running at http://127.0.0.1:1337/. Process PID: ', process.pid);

启动服务

-bash-4.1$ node test.js
Server running at http://127.0.0.1:1337/. Process PID:  12842

无限请求

-bash-4.1$ while true; do curl "http://127.0.0.1:1337/"; done

查看内存情况-bash-4.1$ top -12842
内存不断上涨

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
12842 d  20   0  754m 123m 6296 R 97.3  3.4   0:30.25 node

安装memwatchnpm install --save memwatch
修改test.js

var http = require('http');
var memwatch = require('memwatch');

memwatch.on('leak', function(info) {
    console.error('Memory leak detected: ', info);
});

var server = http.createServer(function (req, res) {
     for (var i=0; i<1000; i++) {
            server.on('request', function leakyfunc() {});
             }

              res.end('Hello World\n');
}).listen(1337, '127.0.0.1');

server.setMaxListeners(0);
console.log('Server running at http://127.0.0.1:1337/. Process PID: ', process.pid);

再重复上面操作,memwatch发现了内存泄漏就会输出这样

-bash-4.1$ node test.js
Server running at http://127.0.0.1:1337/. Process PID:  10640
Memory leak detected:  { start: Tue Jul 07 2015 17:19:51 GMT+0800 (CST),
  end: Tue Jul 07 2015 17:19:52 GMT+0800 (CST),
  growth: 8157816,
  reason: 'heap growth over 5 consecutive GCs (1s) - -2147483648 bytes/hr' }
Memory leak detected:  { start: Tue Jul 07 2015 17:19:52 GMT+0800 (CST),
  end: Tue Jul 07 2015 17:19:52 GMT+0800 (CST),
  growth: 326688,
  reason: 'heap growth over 5 consecutive GCs (0s) - -2147483648 bytes/hr' }
Memory leak detected:  { start: Tue Jul 07 2015 17:19:52 GMT+0800 (CST),
  end: Tue Jul 07 2015 17:19:53 GMT+0800 (CST),
  growth: 2194336,
  reason: 'heap growth over 5 consecutive GCs (1s) - -2147483648 bytes/hr' }

Heap Diffing 可以看某段代码的内内存泄漏情况

// Take first snapshot
var hd = new memwatch.HeapDiff();

// do some things ...

// Take the second snapshot and compute the diff
var diff = hd.end();
console.log(diff);

test.js:

var http = require('http');
var memwatch = require('memwatch');
var heapdump = require('heapdump');


var hd;
memwatch.on('leak', function(info) {
    console.error(info);
    if (!hd) {
        hd = new memwatch.HeapDiff();
    } else {
        var diff = hd.end();
        console.log(diff);
        hd = null;
    }
});

var server = http.createServer(function (req, res) {
     for (var i=0; i<1000; i++) {
         server.on('request', function leakyfunc() {
         });
             }

              res.end('Hello World\n');
}).listen(1337, '127.0.0.1');

server.setMaxListeners(0);
console.log('Server running at http://127.0.0.1:1337/. Process PID: ', process.pid);

输出这样:

-bash-4.1$ node test.js
Server running at http://127.0.0.1:1337/. Process PID:  23138
{ start: Tue Jul 07 2015 19:40:34 GMT+0800 (CST),
  end: Tue Jul 07 2015 19:40:34 GMT+0800 (CST),
  growth: 8009744,
  reason: 'heap growth over 5 consecutive GCs (0s) - -2147483648 bytes/hr' }
{ start: Tue Jul 07 2015 19:40:35 GMT+0800 (CST),
  end: Tue Jul 07 2015 19:40:35 GMT+0800 (CST),
  growth: 325648,
  reason: 'heap growth over 5 consecutive GCs (0s) - -2147483648 bytes/hr' }
{ before:
   { nodes: 141391,
     time: Tue Jul 07 2015 19:40:34 GMT+0800 (CST),
     size_bytes: 13936304,
     size: '13.29 mb' },
  after:
   { nodes: 146593,
     time: Tue Jul 07 2015 19:40:35 GMT+0800 (CST),
     size_bytes: 14040744,
     size: '13.39 mb' },
  change:
   { size_bytes: 104440,
     size: '101.99 kb',
     freed_nodes: 3269,
     allocated_nodes: 8471,
     details:
      [ [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object] ] } }
{ start: Tue Jul 07 2015 19:40:36 GMT+0800 (CST),
  end: Tue Jul 07 2015 19:40:36 GMT+0800 (CST),
  growth: 1785744,
  reason: 'heap growth over 5 consecutive GCs (0s) - -2147483648 bytes/hr' }

heapdump

安装heapdumpnpm install heapdump
人家文档说了Node是v0.6 or v0.8的话要装这个版本npm install heapdump@0.1.0
修改test.js:

var http = require('http');
var memwatch = require('memwatch');
var heapdump = require('heapdump');

memwatch.on('leak', function(info) {
    console.error('Memory leak detected: ', info);
    var file = '/data/home/dongshaoshuai/memleak/' + process.pid + '-' + Date.now() + '.heapsnapshot';
        heapdump.writeSnapshot(file, function(err){
            if (err) {
                console.error(err);
            } else {
                console.error('Wrote snapshot: ' + file);
            }
    });
});


var server = http.createServer(function (req, res) {
     for (var i=0; i<1000; i++) {
            server.on('request', function leakyfunc() {});
             }

              res.end('Hello World\n');
}).listen(1337, '127.0.0.1');

server.setMaxListeners(0);
console.log('Server running at http://127.0.0.1:1337/. Process PID: ', process.pid);

再来无限请求:
while true; do curl "http://127.0.0.1:1337/"; done
输出这样:

-bash-4.1$ node test.js
Server running at http://127.0.0.1:1337/. Process PID:  3034
Memory leak detected:  { start: Tue Jul 07 2015 17:56:39 GMT+0800 (CST),
  end: Tue Jul 07 2015 17:56:40 GMT+0800 (CST),
  growth: 8020976,
  reason: 'heap growth over 5 consecutive GCs (1s) - -2147483648 bytes/hr' }
Wrote snapshot: /data/home/dongshaoshuai/memleak/3034-1436263000668.heapsnapshot
Memory leak detected:  { start: Tue Jul 07 2015 17:56:41 GMT+0800 (CST),
  end: Tue Jul 07 2015 17:56:41 GMT+0800 (CST),
  growth: 326496,
  reason: 'heap growth over 5 consecutive GCs (0s) - -2147483648 bytes/hr' }
Wrote snapshot: /data/home/dongshaoshuai/memleak/3034-1436263001402.heapsnapshot

会在指定目录生成heapsnapshot文件,每次发生内存泄漏都会写入一个新的heapsnapshot文件

.. (up a dir)
/data/home/dongshaoshuai/memleak/
  3034-1436263000668.heapsnapshot
  3034-1436263001402.heapsnapshot
  test.js

3034-1436263000668.heapsnapshot复制到windows下,用Chrome浏览器的Profile功能打开i此文件
这里写图片描述
将文件load进来,就可以看到内存泄漏情况
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值