【问题标题】:Understanding object creation and garbage collection of a NodeJS WebSocket server了解 NodeJS WebSocket 服务器的对象创建和垃圾收集
【发布时间】:2012-08-12 11:25:41
【问题描述】:

我在nodejs中使用ws模块作为web socket服务器,代码的简化版是这样的:

var WebSocketServer = require('ws').Server
var wss = new WebSocketServer({port: 9001});

wss.on('connection', function (ws) {

    // is the ws object created here ?

  ws.on('message', function (message) {
    if (message[0] === '+') {
        ws.name = message.substring(1);
        console.log(ws.name+' connected');
    }
  });

  ws.on('close', function () {
    console.log(ws.name+' disconnected');
    // Will this ws object be deleted ?
  });
});

我想知道:

  • 在连接的每个事件中,是否都会创建一个 ws 对象?
  • 每个连接的客户端是否有一个对象会一直保留在 RAM 中,直到它被垃圾回收?

最重要的是: 如果大量客户端断开连接并且 ws 对象一直存在直到它们被垃圾收集,那么当垃圾收集发生时,我的服务器可能会被锁定很长一段时间,对吗? 我是否应该将这些 ws 对象存储在另一个对象中,这样我就可以使用 delete 关键字并在收到关闭事件后立即删除它们?

如果我这样做,我的可能会有点像这样:

var WebSocketServer = require('ws').Server
var wss = new WebSocketServer({port: 9001});

var websockets = {};

wss.on('connection', function (ws) {
  ws.on('message', function (message) {
    if (message[0] === '+') {
        ws.name = message.substring(1);
        websockets[ws.name] = ws; // Add to the object that stores ws objects
        console.log(ws.name+' connected');
    }
  });

  ws.on('close', function () {
    delete websockets[ws.name]; // Delete from the object
    console.log(ws.name+' disconnected');
  });
});

那么,值得吗?我是否在第二个 sn-p 中编写了对垃圾收集更友好的代码?当垃圾回收发生时,它是否有助于避免长时间锁定?

更新:很抱歉,我刚刚意识到第二个 sn-p 代码是多么愚蠢。当我做websockets[ws.name] = ws时,我实际上是在复制对象的数量......但问题的第一部分仍然有效。

【问题讨论】:

    标签: node.js garbage-collection websocket v8


    【解决方案1】:

    在连接的每个事件上,是否都会创建一个 ws 对象?

    是的。

    每个连接的客户端是否有一个对象会一直保存在 RAM 中,直到它被垃圾回收?

    是的,每个 JavaScript 对象都是如此。

    我是否应该将这些 ws 对象存储在另一个对象中,这样我就可以使用 delete 关键字并在收到关闭事件后立即删除它们?

    没有。使用 delete 关键字不会释放您的内存。事实上,它只是删除引用而已。考虑这个例子:

    var x = { };
    var y = { };
    var z = { };
    x.test = z;
    y.test = z;
    delete x.test;
    

    如您所见,x.test 已被删除(对象 x 不再具有 .test 属性)但 z 根本没有被删除,因为 y 包含对 z 的引用。

    您认为 WS 如何处理多个ws 对象?它将它们存储在内部某个地方。如果你想删除ws 对象,那么只需这样做

    ws.on('close', function () {
        delete ws;
    });
    

    这将确保垃圾收集器在某个时候收集ws。另一方面,我认为WS 已经在内部处理了这个问题,所以你完全不用担心。

    旁注: 在 JavaScript 中无法触发垃圾收集器。但不要担心。如果您达到内存限制,它将自行触发。

    【讨论】:

    • 实际上有一种方法可以在 NodeJS 中触发垃圾收集器:你只需要运行带有标志 --expose_gc 的节点来公开一个触发垃圾收集的 gc() 函数,因为你会这样做您还可以使用标志禁用空闲垃圾收集 --nouse-idle-notification
    • @JoãoPintoJerónimo 我已纠正。不过我认为最好不要乱用垃圾收集器。
    • 我确定你是,我只是指出有一种方法可以触发垃圾收集器。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-28
    • 1970-01-01
    • 1970-01-01
    • 2013-12-03
    • 1970-01-01
    • 2014-11-19
    相关资源
    最近更新 更多