我的'新对象'是否会在套接字断开时被垃圾收集

时间:2016-05-01 16:33:50

标签: javascript node.js socket.io garbage-collection

我有一个代码设置和我想知道它是否被垃圾收集所以我的系统不会开始交换和冻结/崩溃。

假设您保持在系统的正常参数范围内,设置应该能够运行一段不确定的时间(例如,不要同时将1.000.000个用户连接到一个单独的线程进程)

我制作了简化版。

// connection.js

var io, Handler;
io = require('socket.io');
Handler = require('./handler');

io.on('connection', function (socket) {
  new Handler({socket: socket}) 
});
// handler.js

var Handler,
  bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };

  function Handler(arg) {
    this.socket = arg.socket;
    this.test = bind(this.test, this);
    console.log('Handler', 'New connection', this.socket.id);
    this.listeners();
  }

  Handler.prototype.listeners = function() {
    return this.socket.on('test', this.test);
  };

  Handler.prototype.test = function() {
    return console.log('SocketIO', 'test', this.socket.id);
  };


module.exports = Handler;

那么'新的处理程序'在“套接字断开连接事件”发生后进行了垃圾回收?

如果不是我应该如何更改代码?

起初我认为这可能会解决问题

var io, connections, Handler;
io = require('socket.io');
Handler = require('./handler');
connections = {}

io.on('connection', function (socket) {

  connections[socket.id] = new Handler({socket: socket});

  socket.on('disconnect', function (){
    connections[socket.id] = null
  })
});

但这只会创建对'new Handler'的引用,并在断开连接时删除相同的引用。这并不一定意味着'新处理程序'也将被删除。它仍然可以监听和/或做事。

1 个答案:

答案 0 :(得分:1)

只要您的其他代码没有引用它,您的Handler对象就会被垃圾收集。

当实际套接字本身关闭时,系统知道事件处理程序不再存在,因此它们不会阻止垃圾回收。当您删除其上包含事件处理程序的DOM对象时,浏览器会执行相同的操作,以便这些事件处理程序不会阻止垃圾回收。

因此,当socket关闭且socket.io释放它对Javascript套接字对象的任何引用时,应该没有任何代码对Handler对象有任何引用,并且它将有资格进行垃圾收集。

如果您自己引用Handler对象,例如:

var connections = {};
io.on('connection', function (socket) {
    connections[socket.id] = new Handler({socket: socket});
});

然后,您必须在断开连接时清除该引用,如下面的代码所示。否则,此引用将保持活动状态,并使Handler对象不被垃圾回收。

var connections = {};
io.on('connection', function (socket) {
    connections[socket.id] = new Handler({socket: socket});

    socket.on('disconnect', function() {
        delete connections[socket.id];
    })
});

注意:我建议您实际使用delete删除该属性,而不是仅将其设置为null。这样,您就不会在connections对象上构建未使用的属性。