[英]Node.js net socket memory leak?
我有這個劇本 。
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的工作非常簡單:
它創建一個網絡服務器,該網絡服務器在接收到任何數據后立即關閉客戶端,並將其綁定到localhost中的端口3000 。 服務器偵聽時,將執行onListen
函數,該函數實例化連接到服務器的socket
,然后進行堆快照(請注意,在第13行中,我們為套接字設置了50MB bigBuffer
,這只是為了輕松定位它在堆快照中)
在獲取初始快照后, sockets
將一些數據寫入服務器並終止,這是當執行writeEndSnapshot
函數時,它等待下一個刻度,強制執行GC(垃圾收集)周期,然后進行最后的堆快照。
對我來說,很清楚,在拍攝最終快照時,應該已經處置了套接字,因此已經進行了垃圾回收。 但是,加載快照時,這不是我在Google Chrome瀏覽器的分析器中看到的內容。
如您在最終快照中bigBuffer
, bigBuffer
仍然由socket
持有。 我不知道為什么socket
還活着。 socket
owner in TCP @27447
后,我在保留樹中看到的所有內容。 您是否認為這可能是節點的錯誤?
我非常感謝您對了解正在發生的事情的任何幫助。
謝謝!
事實證明,如果只有一個客戶端套接字,則不會收集垃圾。 這是現在帶有兩個套接字的更新腳本:
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);
現在一切正常。 但是,如果將循環更改為僅實例化一個套接字,則會看到該循環在堆中保持活動狀態。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.