简体   繁体   English

node.js-需求错误导致内存泄漏?

[英]node.js - require error causes memory leak?

I have the following program which grows its heap continuously. 我有以下程序会不断增加其堆。 It's a very simple program which repeatedly loads an external file ( SyntaxError ) via require . 这是一个非常简单的程序,可以通过require反复加载外部文件( SyntaxError )。 The external module fails to load because of a syntax error in it. 外部模块由于语法错误而无法加载。

I run the node garbage collector and dump heap size to see if memory is leaking. 我运行节点垃圾收集器并转储堆大小,以查看内存是否泄漏。 If I fix the syntax error in the external file ( SyntaxError.js ), then the leak goes away and memory usage remains constant after a million iterations. 如果我在外部文件( SyntaxError.js )中修复了语法错误,则泄漏消失了,在一百万次迭代后内存使用率保持不变。

Using node version: 0.10.29 with --expose-gc 使用节点版本:0.10.29和--expose-gc

Any insights into what might be happening and how I can avoid mem leak would be greatly appreciated. 对于可能发生的事情以及如何避免内存泄漏的任何见解,将不胜感激。

Test code: 测试代码:

(function() {
  var MAX_ITER_COUNT, MEGABYTE, dumpMem, gc, iterCount, noop, peakMem, test2;

  iterCount = 0;

  MAX_ITER_COUNT = 1000 * 1000;

  peakMem = 0;

  MEGABYTE = 1024 * 1024;

  noop = function() {};

  dumpMem = function() {
    var currentMem;
    currentMem = Math.round(process.memoryUsage().heapUsed / MEGABYTE);
    if (currentMem > peakMem) {
      peakMem = currentMem;
    }
    return console.log("" + iterCount + " - memory is: " + currentMem + "/" + peakMem + " MB");
  };

  gc = function() {
    return global.gc();
  };

  process.on("uncaughtException", function(err) {
    return console.log("Unhandled exception! ", err, err.stack);
  });

  test2 = function() {
    var e;
    iterCount++;
    try {
      /*
      Load a module that has a syntax error to create mem leak, and ignore exception
      */

      require("./SyntaxError");
    } catch (_error) {
      e = _error;
    }
    gc();
    dumpMem();
    return setTimeout(test2, 0);
  };

  test2();

}).call(this);

And SyntaxError.js: 和SyntaxError.js:

(function() {
  'use strict';
  /* y does not exist, and results in exception*/

  var x;

  x = y;

}).call(this);

Seems like this is a node bug. 似乎这是一个节点错误。 I could work around it by putting the try/catch around the body of SyntaxError.js inside SyntaxError.js. 我可以通过将try / catch放在SyntaxError.js 内的 SyntaxError.js主体周围来解决此问题。 My test, simplified from the above: 我的测试,从上面简化:

mem-leak-bug.js: MEM-泄漏bug.js:

for (i=0; i<1000000; i++) {
    try {
        require('./mem-leak--error.js');
    }
    catch (e) { }

    if (i % 1000 === 0) {
        global.gc();
        console.log(i, process.memoryUsage().heapUsed/1e6|0, process.memoryUsage().heapTotal/1e6|0);
    }
}

mem-leak--error.js: MEM泄漏 - error.js:
NOTE: there must be an explicit return in the catch block, else this too leaks memory 注意:catch块中必须有一个明确的返回值,否则这也会泄漏内存

// throw an undefined variable exception
try {
    return x;
}
catch(e) {
    return;
}

Without the try-catch, it leaks memory: 没有try-catch,它将泄漏内存:

% node --expose-gc ar/mem-leak-bug.js
0 1 5
1000 2 14
2000 2 14
3000 3 14
4000 3 23
5000 3 23
6000 4 24

With the try-catch inside SytaxError, it doesn't: 使用SytaxError内部的try-catch,它不会:

% node --expose-gc ar/mem-leak-bug.js
0 1 5
1000 1 7
2000 1 7
3000 1 7
4000 1 7
5000 1 7
6000 1 7
7000 1 7
8000 1 7

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM