我有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);
test.js 的作用非常简单:
它会创建一个 net 服务器,它会在收到任何数据后立即关闭客户端,并将其绑定到 localhost 中的端口 3000 。当服务器侦听时,执行onListen
函数,该函数实例化连接到服务器的socket
,然后获取堆快照(请注意行 13 我们为套接字设置了50MB bigBuffer
,这只是为了在堆快照中轻松找到它)
在获取初始快照之后,sockets
将一些数据写入服务器并结束,这是writeEndSnapshot
函数执行时等待下一个滴答,强制GC(垃圾收集)循环,然后获取最终的堆快照。
对我来说,似乎很清楚,在拍摄最终快照时,套接字应该已经处理好,因此会被垃圾收集。但是,当我加载快照时,这不是我在Google Chrome的分析器中看到的。
正如您在最终快照中看到的那样,bigBuffer
仍然保留socket
。我不知道为什么socket
还活着。 socket
owner in TCP @27447
之后我在保留树中看到的所有内容。你认为这可能是节点的错误吗?
我非常感谢能帮助您了解正在发生的事情。
谢谢!
答案 0 :(得分:0)
事实证明,如果只有一个客户端套接字,则不会收集垃圾。这是一个带有两个套接字的更新脚本:
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);
现在一切正常。但是,如果您更改循环以仅实例化一个套接字,那么您将看到它在堆中保持活动状态。