nodejs 内存泄漏

原创 2015年07月07日 18:29:51

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进来,就可以看到内存泄漏情况
这里写图片描述

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

如何自己检查NodeJS的代码是否存在内存泄漏

追踪NodeJS代码中的内存泄漏一直是一个很有挑战的难题。本文讨论如何从一个node写的应用里自动的跟踪到内存泄漏问题,在这里笔者向大家推荐两款追查内存问题的神器 —— memwatch 和 heap...

MemLeak内存泄漏检测工具

  • 2013年12月26日 14:06
  • 14KB
  • 下载

性能测试瓶颈分析之内存泄漏

关于内存泄漏,相信大家都不陌生,压力测试中经常会出现,本人最近在做一个压力测试中就着实体会了一下,上来分享分享。   内存泄露是指程序中间动态分配了内存,但是在程序结束时没有释放这部分内存,从而造成...

有关android 內存泄漏的问题

  • 2012年11月24日 14:12
  • 80KB
  • 下载

内存泄漏检查类

  • 2015年12月02日 22:26
  • 2KB
  • 下载

Handler使用引起的内存泄漏原因以及解决办法

问题来源在之前我的一篇文章中我就指出了我在项目中如何会出现 内存泄漏的问题的,有兴趣的小伙伴可以点击获取原文看看这个问题出现的来龙去脉,在这里我就不过多做说明了。下面我们用最简单直接粗暴的方式进入主题...

Android内存泄漏案例分析

  • 2015年08月31日 09:47
  • 949KB
  • 下载

深入分析 ThreadLocal 内存泄漏问题

前言 ThreadLocal 的作用是提供线程内的局部变量,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或者组件之间一些公共变量的传递的复杂度。但是如果滥用 ThreadLocal,就...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:nodejs 内存泄漏
举报原因:
原因补充:

(最多只允许输入30个字)