5

我想我在 jQuery UI 可拖动库中发现了内存泄漏,虽然问题可能是由 Meteor 引起的,但我不确定。

当我的应用第一次被一群用户全天使用时,我第一次注意到这一点。我在选项卡中打开了应用程序,到一天结束时,它太慢了,无法使用。我检查了内存使用情况,发现它几乎使用了整个 GB 的内存。

为了重现这个问题,我编写了一个 PhantomJS 脚本,该脚本登录到应用程序并进行大量更新,同时在 Chrome 的开发工具中记录内存使用情况。所以我去寻找导致问题的代码,发现它是我在模板的渲染事件中放置元素的可拖动/可放置事件。

这是我的幻像脚本以可拖动方式运行时的内存使用示例: 在此处输入图像描述

这是我没有可拖动的内存使用情况: 在此处输入图像描述

注意:我尝试使用零配置选项将可拖放和可拖放一起以及单独进行,但发现泄漏没有明显变化。

从第一张图中可以看出,脚本停止运行后(大约 1.4 分钟)内存使用量并未释放,并且内存使用量有相当大的增加(14.3 MB 到 169 MB)。这正在运行大约 300-500 次更新(这可能并不是那么不切实际,尤其是在有很多用户的一整天过程中)。

我认为这里的关键是 Chrome 在时间轴选项卡中为您提供的节点数。根据 DOM 节点计数,脚本运行后有 100 000+ 个 DOM 节点,第二个大约有 1000 个。

我创建了一个完全独立的项目来确保这个问题是真实的。我把它放在github上供任何人玩。我的 phantomJS 脚本位于根目录中。

https://github.com/davidworkman9/jQueryDraggableMemLeakWithMeteor

我不确定从这里去哪里,是到 Meteor 还是 jQuery UI,或者如果没有从这些软件包中的任何一个修复,问题是否可以解决。

4

1 回答 1

0

对于遭受此问题的任何人,我设计了一个临时修复程序(此修复程序适用于每个模板重新渲染)。

(function () {
    var oldRender = Spark.renderToRange;
    Spark.renderToRange = function (range, htmlFunc) {
        var oldFunc = htmlFunc;
        htmlFunc = function () {

            // put in clean up code here Example:
            if(range._start === $('#myTemplate')[0]) {
                $('#myTemplate').find('.ui-draggable').draggable('destroy');
            }
            // end clean up code

            return oldFunc.apply(this, arguments);
        };
        return oldRender.apply(this, arguments);
    };
})();

Google Groups 论坛上的一位 Meteor Core 开发人员告诉我(链接)他们正在重写模板包,这将解决这个问题。

于 2013-10-03T20:36:16.803 回答