Repository navigation
Closed
Labels
memoryIssues and PRs related to Node.js memory management or memory footprint.Issues and PRs related to Node.js memory management or memory footprint.netIssues and PRs related to the net subsystem.Issues and PRs related to the net subsystem.
Description
Recently I was stress testing my API and discovered that even very simple net server has a memory leaks. Is it possible that there's something wrong with it?
Server code:
"use strict"
var net = require('net');
// Keep track of the chat clients
var clients = [];
function clean() {
global.gc();
console.log('Current memory usage: ', process.memoryUsage());
setTimeout(clean, 30000);
}
setTimeout(clean, 30000);
var proxy = net.createServer(function (socket) {
// Identify this client
socket.name = socket.remoteAddress + ":" + socket.remotePort
// Put this new client in the list
clients.push(socket);
socket.on('close', function () {
clients.splice(clients.indexOf(socket), 1);
socket = null;
});
socket.on('error', function (err) {
clients.splice(clients.indexOf(socket), 1);
socket = null;
});
});
console.log('Current memory usage: ', process.memoryUsage());
proxy.listen(2919);
Testing client bash script:
#!/bin/bash
for i in $(seq 1 1 10000)
do
curl -m0.001 http://127.0.0.1:2919/;
done
Starting iojs server(3.2.0):
$ node --expose-gc test.js
Current memory usage: { rss: 21942272, heapTotal: 9275392, heapUsed: 3732936 }
Current memory usage: { rss: 36179968, heapTotal: 26806272, heapUsed: 4428112 }
Current memory usage: { rss: 47865856, heapTotal: 44349184, heapUsed: 4496016 }
Current memory usage: { rss: 47325184, heapTotal: 40221440, heapUsed: 4472480 }
After 10k calls server memory consumption increased from 21 to 45.5MB. Is that scripts' fault?
Metadata
Metadata
Assignees
Labels
memoryIssues and PRs related to Node.js memory management or memory footprint.Issues and PRs related to Node.js memory management or memory footprint.netIssues and PRs related to the net subsystem.Issues and PRs related to the net subsystem.
Activity
Fishrock123 commentedon Aug 31, 2015
@Cinderella-Man Does this also happen with io.js 2.5.0?
mscdex commentedon Sep 1, 2015
From what I'm seeing, the server process stabilizes at ~59-60MB rss, even if you keep restarting the client bash script.
The stabilized memory amount can be improved a little bit (~2MB total on average) by draining the socket buffers sooner by adding
socket.resume();at the end of the socket connection handler.Additionally, if you force the
gc()to run more often (e.g. every 5 seconds vs. every 30 seconds), the stabilized memory amount is much lower, ~31-33MB.mscdex commentedon Sep 1, 2015
With io.js v2.5.0 I'm seeing roughly the same memory differences, except the rss has dropped uniformly for all scenarios by ~1MB.
rvagg commentedon Sep 1, 2015
the new Buffer implementation makes rss much more unstable over longer runs now than it used to, thanks to something in
ArrayBuffer, zoom out to 2d or 7d and look at the bottom graph: http://128.199.216.28:3000/dashboard/db/memory-testsChALkeR commentedon Sep 1, 2015
gc()run does not necessary clean all the garbage.free-d, because the memory allocator behaves that way. That memory is not returned to the system, but is used later for further allocations done by the process. It's not node/io.js fault, even a simple c++ program behaves that way: it depends on the size of allocated memory chunks — large chunks are allocated usingmmapand are returned to the system (rss decreases), small chunks are allocated usingsbrkand are not returned to the system (rss does not decrease). Given that the most common use-cases (in most programs) involve allocations of small memory chunks, you get almost non-decreasing RSS.My results for your script (given that by
-m0.001you meant curl to time-out after 1 ms, andglobal.gc()is meant to do the same asgc()):Second client run on the same server:
You could see that both
RSSandheapUsedhave stabilized.While @rvagg is correct here about the new
Bufferimplementation, this specific test-case does not look problematic to me. Also, the problems withBufferare not memory leaks.Btw, speaking of 1.: if you replace a
gc()call with four subsequentgc()calls (I do not recommend doing that on a production server), you will see thatheapUsedremains more stable (two client runs here):ChALkeR commentedon Sep 3, 2015
Should we close this?
mscdex commentedon Sep 3, 2015
Closing this for now. If someone can prove that there is a continual leak that never stops, then we can reopen this at that time.