【问题标题】:Javascript memory leak cleanup in window.unloadwindow.unload 中的 Javascript 内存泄漏清理
【发布时间】:2008-12-04 08:49:17
【问题描述】:

Javascript 客户端应用程序。

试图消除内存泄漏会导致代码丑陋(至少可以这么说)。

我试图在 window.unload 中进行清理,而不是弄乱所有试图避免它们的代码。

我们主要使用element.onevent=function(){..}; 模式,这会导致关闭(大部分需要)和内存泄漏。

我们不使用 javascript 框架。

关于如何在退出时正确清理有什么想法吗?

有没有人做同样的事情,或者你想避免他们?

【问题讨论】:

    标签: javascript ajax web-applications memory-leaks


    【解决方案1】:

    最好的解决方案是让您推出自己的方法来管理事件处理。因此,在附加事件处理程序时,您的方法可以跟踪所有添加的事件。在卸载时,它可以注销所有处理程序。

    我知道您说过您不使用库,但您可以使用它们的代码作为灵感。当您使用 Ext.EventMgr.addListener 时,Ext-js 会这样做。

    这是一个简单的 EvtMgr obj,您可以使用它开始。太简单了,这里没法给大家写完。随意询问有关您喜欢但不知道该怎么做的事情的问题。另请注意,我不会使用 element.onclick 方法,因为您只能添加一个处理程序。我这样做是因为你说你就是这样做的。

    var EvtMgr = (function(){
      var listenerMap = {};
    
      // Public interface
      return {
        addListener: function (evtName, node, handler) {
          node["on" + evtName] = handler;
          var eventList = listenerMap[evtName];
          if (!eventList) {
            eventList = listenerMap[evtName] = [];
          }
          eventList.push(node);
        },
    
        removeAllListeners: function() {
          for (var evtName in listenerMap) {
            var nodeList = listenerMap[evtName];
            for (var i=0, node; node = nodeList[i]; i++) {
              node["on" + evtName] = null;
            }
          }
        }
      }
    })();
    

    另外,请注意带有闭包的处理程序并不是造成泄漏的唯一方法。看我对这个问题的评论Javascript memory leaks after unloading a web page

    另外,我不明白为什么有些人害怕图书馆。 jquery 很小,ext core 也是。如果您在不了解 js 的情况下使用它们,它们可能会很危险。但是如果你的 js 技能扎实,你可以通过重用他们的代码来节省很多工作。当我需要了解某事是如何完成的时,我每天都在使用 ext-js。这就是我给你这几行代码的方式。

    在管理内存泄漏时要考虑的另一个问题是确保在从 DOM 中删除元素时删除处理程序(node.innerHTML 或任何其他方式)。如果这样做,则应从已从 DOM 中删除的节点中删除处理程序。需要做一些工作才能使其发挥作用,但这应该成为您战略的一部分。

    【讨论】:

      【解决方案2】:

      一种避免事件内存泄漏的解决方案是委托。简而言之,您将事件处理程序附加到父对象而不是子对象。由于传播,对子项的单击也将注册为对父项的单击,从而触发您的处理程序。通过检查事件的目标属性,您可以决定如何处理它。

      由于处理程序附加到父级,您可以添加或删除子级而不必担心泄漏。

      更详尽的解释可以在这里找到:http://www.robertnyman.com/2008/05/04/event-delegation-with-javascript/

      这里有一个演示:http://www.robertnyman.com/test/event-delegation/event-delegation.html

      【讨论】:

        【解决方案3】:

        我不确定您所说的清理是什么意思,因为 JavaScript 具有自动内存管理功能。但无论如何,据我了解,在卸载窗口后,与 JS 相关的所有内存也会被释放。毕竟 - 页面卸载后不再执行 JS,对吧?

        【讨论】:

        • 对不起,不!有两个 GC(javascript 和 DOM)。独立工作。如果您连接 javascript 和 DOM 对象(我们一直这样做),就会发生泄漏。
        【解决方案4】:

        从我对此的大部分调查来看,没有什么好的方法可以做到这一点。每个单独的浏览器都有自己的垃圾收集实现。

        Firefox 还不错,但例如 IE6 就很糟糕。尝试创建超过 60 个对象的任何东西,IE6 会变得非常缓慢。

        只是其中一件事,我已经接受了。

        【讨论】:

          猜你喜欢
          • 2021-07-13
          • 2016-05-31
          • 2014-04-08
          • 2012-04-16
          • 2010-11-13
          • 1970-01-01
          • 2011-02-28
          • 2014-04-23
          相关资源
          最近更新 更多