IE8中Dojo 1.7.2导致内存泄漏

时间:2013-01-10 09:54:23

标签: javascript memory-leaks internet-explorer-8 dojo

我们使用Dojo开发了一个丰富的Web应用程序(使用许多不同的视图,许多按钮,视图之间的事件等)。任何数据都通过Rest接口异步加载。

现在我们意识到,在Internet Explorer 8中,如果应用程序的URL在相同的选项卡/浏览器窗口中打开两倍或更多倍,并且很快会导致内存不足,那么我们的应用程序的占用空间就会很大并且会增长。

似乎Dojo不会断开任何事件处理程序/ DOM节点。

我将其跟踪到一个只有一个Dojo按钮小部件的简单html页面,并使用sIEve(IE8的内存泄漏分析器)分析了html页面。如果再次调用html页面,则不会释放某些DOM节点(成为孤儿)。

是否有任何设置/技巧/模式可以防止孤儿?

我认为这种行为会导致我们的Dojo应用程序占用大量空间,而这些应用程序在离开应用程序URL时不会被释放。

这是示例html页面:

<html>
<head>
    <title>MemLeak Test</title>
    <style>
        @import "../themes/claro/claro.css";
    </style>
    <script
        type="text/javascript"
        data-dojo-config="'parseOnLoad':true"
        src="../js/dojo-release/dojo/dojo.js"></script>
    <script type="text/javascript">
        require([ "dojo/parser" ]);
        require([ "dijit/form/Button" ]);
    </script>
</head>
<body class="claro">
    <h1>Memory Leak?</h1>
    <input
        type="button"
        dojoType="dijit.form.Button"
        label="Button"></input>
</body>

在sIEve中打开示例html文件两次后,它报告了18个孤立的项目: HEAD,SCRIPT,DIV,SPAN(以不同的顺序重复);所有只有1 Ref并标记为泄漏! (对不起,我无法发布任何截图)

关于该主题的任何帮助。

1 个答案:

答案 0 :(得分:0)

问题是你永远不会销毁这些小部件,因此浏览器会在内存中保留所有对事件,dom节点等的引用。 您可以使用unload事件侦听器部分解决问题,并调用您创建的窗口小部件的destroy方法。

以下是一个例子:

require(['dojo/_base/unload', 'dojo/_base/array'], function(unload, array){
    unload.addOnUnload(function(){
        array.forEach(myWidgets, function(wgt){
            wgt.destroy();
        });
    });
});

或者,如果您没有对小部件的引用,您可以遍历dijit注册表:

require(['dojo/_base/unload', 'dojo/_base/array', 'dijit/registry'], function(unload, array, dijitRegistry){
    unload.addOnUnload(function(){
        array.forEach(dijitRegistry.toArray(), function(wgt){
            wgt.destroy();
        });
    });
});