当对象被删除时,对象内的setInterval是否会阻止垃圾回收?

时间:2017-01-02 14:59:16

标签: javascript garbage-collection

我正在开发一个小的Websocket项目(使用Socket.io),我在那里使用类似的类:

function myClass() {
    // start server sync
    window.setInterval(this.update.bind(this), 14);

    // listen for socket.io events
    io.on('my-event', doStuff);
}

该类的多个实例存储在数组中。 一段时间后,实例会被删除:

myArr.splice(index, 1);

数组是唯一的位置,我将实例存储在其中,所以我想,从数组中删除后,它们会被垃圾收集器删除。

相反,我注意到,他们仍然回应我的websocket事件。我想知道间隔是否阻止对象被删除,因为它绑定到窗口对象。 在删除类实例之前是否需要清除间隔?

或者事件监听器是否阻止删除该对象?

2 个答案:

答案 0 :(得分:3)

  

......实例会被删除:

myArr.splice(index, 1);
     

...相反,我注意到,他们仍然回应我的websocket事件。我想知道间隔是否阻止对象被删除,因为它绑定到窗口对象。在删除类实例之前是否需要清除间隔?

是的,你需要做更多的清理工作。你需要:

  • 清除时间间隔,清除与之关联的资源,并使其释放对this.update.bind(this)创建的函数的引用(后者又引用该对象,将其保留在内存中)。

  • 删除所有事件侦听器(例如,Web套接字事件),这将删除对事件处理函数的引用,这些函数可能引用了将其保留在内存中的对象。

  • 确保也发布对该对象的任何其他直接或间接引用(例如在任何其他绑定函数中)。

答案 1 :(得分:0)

是的,引用某个函数的值或范围可以防止其冒充。

事实上,从函数到对象和作用域的指针是JavaScript中内存泄漏的主要原因之一,此类中最常见的是闭包,通常与事件回调相关(包括该类别中的计时器)。

当您希望对象可以被垃圾处理时,请务必取消注册所有事件处理程序,并删除计时器(请注意,从DOM中删除元素并且不保留对它的引用时,将删除事件处理程序)。