I have this script .
var net = require("net")
, heapdump = require("heapdump");
function onConnection (client) {
client.on("data", function (data) {
client.end();
});
};
function onListen () {
var socket = net.connect({host: "127.0.0.1", port: 3000});
socket.bigBuffer = new Buffer(50000000); //50MB Buffer
heapdump.writeSnapshot(__dirname + "/initial.heapsnapshot", function writeInitialSnapshot () {
console.log("Wrote initial heap snapshot");
socket.write("data");
});
socket.on("close", function () {
writeEndSnapshot();
});
};
function writeEndSnapshot () {
setTimeout(function () {
console.log("Running GC");
gc();
heapdump.writeSnapshot(__dirname + "/final.heapsnapshot", function writeFinalSnapshot () {
console.log("Wrote final heap snapshot");
});
}, 1000);
};
net.createServer(onConnection).listen(3000, onListen);
What test.js does is pretty straight forward:
It creates a net server, which closes the clients right after receiving any data, and binds it to the port 3000 in localhost . When the server listens, the onListen
function is executed, which instantiates a socket
that connects to the server, and then takes a heap snapshot (please notice that in the line 13 we set a 50MB bigBuffer
to the socket, this is just to easily locate it in the heap snapshot)
Right after taking the initial snapshot, the sockets
writes some data to the server and gets ended, this is when the writeEndSnapshot
function gets executed, which waits for the next tick, forces a GC (garbage collection) cycle, and then takes a final heap snapshot.
It seemed pretty clear for me that by the time the final snapshot is taken, the socket should have been disposed, and therefore, garbage-collected. However, this is not what I'm seeing in the Google Chrome's profiler when I load the snapshots.
As you can see in the final snapshot, bigBuffer
is still held by the socket
. I have no idea why the socket
is still alive. All I can see in the retainers tree after socket
is owner in TCP @27447
. Do you think this might be a node's bug?
I'd really appreciate any help to understand what's going on.
Thank you!
It turns out that if there's only one client socket, this wont get garbage collected. Here's an updated script now with two sockets:
var net = require("net")
, heapdump = require("heapdump");
function onConnection (client) {
client.on("data", function (data) {
client.end();
});
};
function onListen () {
var socket
, sockets = []
, closedSockets = 0;
for (var i = 0; i < 2; i++) {
socket = net.connect({host: "127.0.0.1", port: 3000});
sockets.push(socket);
socket.bigBuffer = new Buffer(25000000); //25MB Buffer
socket.on("close", function () {
if (++closedSockets == sockets.length) {
writeEndSnapshot();
};
});
};
heapdump.writeSnapshot(__dirname + "/initial.heapsnapshot", function () {
console.log("Wrote initial heap snapshot");
for (var i = 0; i < sockets.length; i++) {
sockets[i].write("data");
};
});
};
function writeEndSnapshot () {
setTimeout(function () {
console.log("Running GC");
gc();
heapdump.writeSnapshot(__dirname + "/final.heapsnapshot", function () {
console.log("Wrote final heap snapshot");
});
}, 1000);
};
net.createServer(onConnection).listen(3000, onListen);
Everything works fine now. However, if you change the loop to instantiate just one socket, you'll see it keeps alive in the heap.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.