【问题标题】:Will my 'new Object' be garbage collected on socket disconnect我的“新对象”会在套接字断开时被垃圾收集吗
【发布时间】:2016-05-01 16:33:49
【问题描述】:

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

假设您保持在系统的正常参数范围内,设置应该能够运行不确定的时间(例如,因此不要同时将 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
  })
});

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

【问题讨论】:

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


    【解决方案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 对象上获得未使用的属性。

    【讨论】:

    • 谢谢伙计! =D 而且删除确实更好!
    猜你喜欢
    • 1970-01-01
    • 2010-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多