【问题标题】:Will using prototype function as event handler cause memory leak?使用原型函数作为事件处理程序会导致内存泄漏吗?
【发布时间】:2018-04-19 20:02:22
【问题描述】:
var foo = function () {
}

foo.prototype.bar = function () {
}

var test = function () {
    var socket = new WebSocket("ws://localhost");
    socket.onopen = foo.prototype.bar; 
    //Or socket.addEventListener('open', foo.prototype.bar)
}

test();

socket 应该在测试执行后立即进行 GC。但它有一个 onopen 处理程序,它持有对套接字对象的引用。

由于函数是在原型上定义的,所以它将永远存在(我认为)。问题是该功能是否会阻止套接字获得 GCed。

I.E.是否需要在打开事件后取消订阅以防止内存泄漏?

【问题讨论】:

  • 如果你为foo.prototype设置了一个特定的实例,你可以在完成后将其清空。
  • @ScottMarcus 即使我将其清空,引用仍然在原型上定义的函数上,不是吗..
  • 如果你将原型清空,它就不会存在附加函数。
  • @ScottMarcus im 使用 typescript 类并且 ts 喜欢原型。我只是想知道我是否需要清除类中定义的所有事件处理程序,或者我是否可以避免内存泄漏。 (我对答案很好奇。想知道浏览器是否可以做一些魔法来避免这种情况)
  • 这应该很容易测试,但我不认为这是一个问题 - 引用是从要收集的对象到原型,而不是相反。

标签: javascript memory-leaks garbage-collection


【解决方案1】:

由于函数是在原型上定义的,所以它将永远存在(我认为)。

是的。

问题是这个函数会阻止套接字被 GCed 吗?

没有。套接字对象引用的是函数,而不是相反。

socket 应该在测试执行后立即进行 GC。

是的,socket 变量是,但是您创建的套接字对象(包含对处理程序的引用)仍然存在 - 它被从网络接收有效负载的内部侦听器引用。

是否需要在打开事件后取消订阅以防止内存泄漏?

没有。只有当你想保持套接字打开但停止监听时,你才需要取消订阅。

但是,当您完成测试后,您需要关闭套接字!

【讨论】:

    猜你喜欢
    • 2010-09-06
    • 1970-01-01
    • 2012-11-02
    • 2011-11-14
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 2012-12-01
    • 2011-01-13
    相关资源
    最近更新 更多