2013-05-08 137 views
1

*更新 - 增加了一个示例代码视图的一个*垃圾收集骨干

这已经讨论了很多次,我已经经历了很多的建议了这个话题,但我还是不要没有任何运气。

我的应用程序是基于选项卡的,即用户在全局搜索框中搜索实体,并在选择实体时生成视图/模型,并在新选项卡下呈现视图。用户可以通过重复上述操作打开多个选项卡处理。

我面临的问题是每次打开一个新选项卡时,我都可以看到浏览器内存消耗量增加了大约6 MB(每个选项卡显示的数据取自&最大为60kb)。

不仅如此,但当我关闭一个标签时,我可以看到我的自定义关闭功能(复制下面)被调用该选项卡下的每个视图,但不知何故浏览器内存不下降。这对我来说意味着垃圾回收不起作用,或者视图/模型没有被正确清理。

任何帮助将不胜感激。

define([ 
    "hbs!modules/applications/templates/applications", 
    "vent" 
], 
function (tpl, vent) { 

    var View = Backbone.Marionette.ItemView.extend({ 

     className: 'modApplications', 

     template: { 
      type: 'handlebars', 
      template: tpl 
     }, 

     refresh: function(){ 
      self.$('.body-of-table').css('visibility', 'hidden'); 
      self.$('.application-panel .spinnerDiv').addClass('loading'); 
      this.model.fetch().always(function(){ 
       self.$('.application-panel .spinnerDiv').removeClass('loading'); 
      }); 
     }, 

     initialize: function(){ 
      this.model.on('change', this.render, this); 
      vent.bindTo(vent, 'updateApplications', this.refresh, this); 
     }, 

     onShow: function(){ 
      var self = this; 
      this.$el.on('click', '.action-refresh', function(e) { 
       self.refresh(); 
       e.preventDefault(); 
      }); 
     }, 

     close: function() { 
      _.each(this.bindings, function (binding) { 
       binding.model.unbind(binding.ev, binding.callback); 
      }); 
      this.bindings = []; 
      this.unbind(); 
      this.off(); 
      this.model.off('change'); 
      this.model.unbind('change', this.render, this); 
      this.remove(); 
      delete this.$el; 
      delete this.el; 
      if(console) console.log("kill : view.applications"); 
     } 

    }); 

    return View; 

}); 
+0

恐怕这不足以代表您向我们展示的代码。 JavaScript中的内存泄漏很可能是由于未被清除的对象引用;特别是DOM节点和JS对象之间的交叉引用很脏。检查代码是否有任何对子对象和方法的引用。还要确保DOM元素不会(例如通过事件处理程序)引用匿名函数(即封闭)。 – Kiruse 2013-05-08 14:46:46

+0

我已更新帖子并添加了我使用的典型视图结构。你能否看看我是否错过了视野内的任何清洁。 – kapricanon 2013-05-08 14:55:05

+0

不幸的是,我并没有在backbone.js上工作过很多。我不知道它如何处理事件绑定。例如,我不知道如何解除'vent.bindTo(vent,'updateApplications',this.refresh,this)'或者它是否足以简单地删除对this的引用$ el'你已经绑定了一个点击事件。您也可能错过了在返回后清除“视图”。就像我所说的那样,泄漏内存的潜力最大的区域包括对象引用,特别是DOM和JS之间的交叉引用,如事件处理程序。虽然API应该为你照顾这些... – Kiruse 2013-05-08 15:08:41

回答

1

发现问题&修复。

问题是,我正在使用一个全球Marionette.EventAggregator所有新标签。这被用作在标签内的各个部分之间进行通信的手段。现在,当关闭标签时,main.js文件仍然引用全局通风口,因为其他标签仍在使用它。这是对封闭标签的引用仍然存在的地方,因此视图/模型没有显示出来。

要解决这个问题,我为每个选项卡创建了一个单独的通风口,并使用该通风口对象触发该选项卡内的任何事件。在选项卡关闭操作上,我取消绑定所有事件,并为将要关闭的选项卡分配一个空引用。

希望这可以帮助未来的人。