最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - examples of closures in node.js that would cause memory leaks - Stack Overflow

programmeradmin2浏览0评论

In trying to debug memory leaks in NodeJS, I'm finding it quite difficult (given the lack of profiling tools that I am aware of).

I thought I'd go back to basics and make sure I understand how a memory leak would be created specifically in NodeJS. I'm confused about the types of closures that might cause memory leaks and am unsure of what the garbage collector needs in order to free up that memory.

Could you give me some examples of basic patterns that would cause a memory leak in Node.js?

In trying to debug memory leaks in NodeJS, I'm finding it quite difficult (given the lack of profiling tools that I am aware of).

I thought I'd go back to basics and make sure I understand how a memory leak would be created specifically in NodeJS. I'm confused about the types of closures that might cause memory leaks and am unsure of what the garbage collector needs in order to free up that memory.

Could you give me some examples of basic patterns that would cause a memory leak in Node.js?

Share Improve this question edited Jan 12, 2012 at 0:40 Alex Wayne 187k52 gold badges324 silver badges357 bronze badges asked Jan 11, 2012 at 7:49 crickeyscrickeys 3,1153 gold badges28 silver badges27 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 18

Not a "leak" exactly, but this can be a common pitfall.

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

  return function() {
    return c;
  };
})();

This returns a function that references a scope, and every single local var in that scope will be kept, even though only one of those values are needed. This results in more memory usage than you need, especially if your function uses a small variable, but there are large values in that scope that you dont need to keep referencing.


How to fix it?

Simple option is to null out the variables you dont care about at the end of your function. The variables are still in scope, but their data would be released.

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;
  };
})();

Or you could break anything that uses temp vars into it's own function so their scopes can be released. This is a better solution for a larger project.

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;
  };
})();
  1. You can use node-inspector to debug node apps with the Chrome dev tools.

  2. The accepted answer about unused closure variables is wrong because in modern JS engines, only those variables actually referenced in the inner function are included in the closure scope. The rest are automatically garbage collected. In other words, this theoretical condition will never actually occur in Node.

  3. For a real (and fairly common) example using express, you could create middleware that loads a file into memory for each request and then throw an unhandled exception in that same request, catch the thrown exception, and then fail to exit the process.

The thrown exception will cause the loaded request resources to linger instead of being cleaned up at the end of the request/response cycle.

Failing to exit the process when the exception occurs means that instead of shutting down and being restarted by something like PM2 or Forever, Node will ignore the error and keep serving new requests as if nothing happened. Since the resources aren't being cleaned up, the process will consume more and more memory over time until it drags down the performance of the machine and eventually runs out of space to allocate new resources.

That would obviously have a negative impact on the user experience.

See also Why Would an Exception Cause Resource Leaks in Node.js.

From: http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml?showone=Closures#Closures

One thing to keep in mind, however, is that a closure keeps a pointer to its enclosing scope. As a result, attaching a closure to a DOM element can create a circular reference and thus, a memory leak. For example, in the following code:

function foo(element, a, b) {
  element.onclick = function() { /* uses a and b */ };
}

the function closure keeps a reference to element, a, and b even if it never uses element. Since element also keeps a reference to the closure, we have a cycle that won't be cleaned up by garbage collection. In these situations, the code can be structured as follows:

function foo(element, a, b) {
  element.onclick = bar(a, b);
}

function bar(a, b) {
  return function() { /* uses a and b */ }
}
发布评论

评论列表(0)

  1. 暂无评论