2013-05-08 132 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文件仍然引用全局通風口,因爲其他標籤仍在使用它。這是對封閉標籤的引用仍然存在的地方,因此視圖/模型沒有顯示出來。

要解決這個問題,我爲每個選項卡創建了一個單獨的通風口,並使用該通風口對象觸發該選項卡內的任何事件。在選項卡關閉操作上,我取消綁定所有事件,併爲將要關閉的選項卡分配一個空引用。

希望這可以幫助未來的人。