node.js中的闭包示例会导致内存泄漏

cri*_*eys 15 javascript node.js

在尝试调试NodeJS中的内存泄漏时,我发现它非常困难(考虑到我所知道的缺少分析工具).

我想我会回到基础并确保我理解如何在NodeJS中专门创建内存泄漏.我对可能导致内存泄漏的闭包类型感到困惑,并且不确定垃圾收集器需要什么才能释放内存.

你能给我一些基本模式的例子,这些模式会导致Node.js中的内存泄漏吗?

Ale*_*yne 18

不完全是"泄漏",但这可能是一个常见的陷阱.

var fn = (function() {
  var a = "super long string ...";
  var b = "useless value";
  var c = "Hello, World!";

  return function() {
    return c;
  };
})();
Run Code Online (Sandbox Code Playgroud)

这将返回引用范围的函数,并且将保留该范围中的每个局部var,即使只需要其中一个值.这会导致比您需要的内存使用量更多,特别是如果您的函数使用一个小变量,但在该范围内有大量值,您不需要继续引用.


怎么解决?

简单的选择是在函数结束时清空你不关心的变量.变量仍然在范围内,但它们的数据将被释放.

var fn = (function() {
  var a = "super long string ...";
  var b = "useless value";
  var c = "Hello, World!";

  // do stuff with a and b

  a = b = null;

  return function() {
    return c;
  };
})();
Run Code Online (Sandbox Code Playgroud)

或者你可以将使用temp vars的任何东西分解成它自己的函数,这样就可以释放它们的作用域.对于更大的项目,这是一个更好的解决方案.

var doSetup = function() {
  var a = "super long string ...";
  var b = "useless value";
  // do stuff with a and b
};

var fn = (function() {
  doSetup();

  var c = "Hello, World!";

  return function() {
    return c;
  };
})();
Run Code Online (Sandbox Code Playgroud)

  • 这是一个非常理论上的"泄漏".实际上,V8优化了它们的环境(闭包)记录和gc这些变量.也就是说这实际上根本不是一个问题(除了在存在本地证据等的潜在病态案例中,我不记得它是如何处理的,但这几乎从来没有). (6认同)