Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

node.js file memory leak?

I'm seeing a memory leak with the following code:

while (true) {
  console.log("Testing.");
}

I have tried defining the string and just using a constant, but it leaks memory, still:

var test = "Testing.";
while (true) {
  console.log(test);
}

The same leak happens if I use a file instead of the standard log:

var test = "Testing.";
var fh = fs.createWriteStream("test.out", {flags: "a"});
while (true) {
  fh.write(test);
}

I thought maybe it was because I wasn't properly closing the file, but I tried this and still saw the leak:

var test = "Testing";
while (true) {
  var fh = fs.createWriteStream("test.out", {flags: "a"});
  fh.end(test);
  fh.destroy();
  fh = null;
}

Does anyone have any hints as to how I'm supposed to write things without leaking memory?

like image 771
facetious Avatar asked Jan 13 '12 20:01

facetious


1 Answers

This happens because you never give node a chance to handle "write successful" events, so they queue up endlessly. To give node a chance to handle them, you have to let the event loop do one iteration from time to time. This won't leak:

function newLine() {
  console.log("Testing.");
  process.nextTick(newLine);
}
newLine();

In real use cases, this is no issue because you nearly never have to write out so huge amounts of data at once that this matters. And if it does, cycle the event loop from time to time.

However, there's also a second issue with this that also occurs with the nextTick trick: Writing is async, and if the console/file/whatever is slower than node, node buffers data endlessly until the output is free again. To avoid this, you'll have to listen for the drain event after writing some stuff - it tells you when the pipe is free again. See here: http://nodejs.org/docs/latest/api/streams.html#event_drain_

like image 107
thejh Avatar answered Oct 13 '22 05:10

thejh