IE8 中 Dojo 1.7.2 导致的内存泄漏

Posted

技术标签:

【中文标题】IE8 中 Dojo 1.7.2 导致的内存泄漏【英文标题】:Memory leak caused by Dojo 1.7.2 in IE8 【发布时间】:2013-01-10 09:54:22 【问题描述】:

我们使用 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】:

问题是您永远不会破坏这些小部件,因此浏览器会将所有对事件、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();
        );
    );
);

【讨论】:

以上是关于IE8 中 Dojo 1.7.2 导致的内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章

避免dojo中的内存泄漏?

解决android中EditText导致的内存泄漏问题

分析 ThreadLocal 内存泄漏问题

由于固定的 GC 句柄/没有可见的 gc 根导致内存泄漏

深入分析 ThreadLocal 内存泄漏问题

转载深入分析 ThreadLocal 内存泄漏问题