2016-03-22 9 views
0

私はルータでは、このバックボーン・メモリ・リークが機能しない?

  function test() { 
       self.topbarView = new TopbarView(); 
       self.topbarView.render(); 
       GhostviewHunter.addView(self.topbarView); 
      } 

      function clean() { 
       console.log(GhostviewHunter.currentViews.length); 
       GhostviewHunter.clean(); 
      } 
      setInterval(test, 1000); 
      setInterval(clean, 1000); 

ghostviewhunterは、ビューを削除/クリーンアップする必要があります

define('ghostviewHunter', [], function() { 

    var GhostviewHunter = function() {}; 

    GhostviewHunter.prototype.currentViews = []; 

    GhostviewHunter.prototype.addView = function(view) { 
     this.currentViews.push(view); 
    } 

    GhostviewHunter.prototype.clean = function() { 
     _.each(this.currentViews, function(view) { 
      view.remove(); 
     }); 
     this.currentViews.length = 0; 
    } 

    GhostviewHunter.__instance = null; 

    GhostviewHunter.getInstance = function() { 
     if(GhostviewHunter.__instance == null) { 
      GhostviewHunter.__instance = new GhostviewHunter(); 
     } 
     return GhostviewHunter.__instance; 
    } 

    return GhostviewHunter.getInstance(); 

}) 

上面図は、モデルをフェッチしている、モデルはのsetInterval機能を持つすべての1secondeが更新されます。

私はそのことを考えました。私は、アプリケーションを監視するときにメモリリークが非常に迅速です十分であろう。

EDIT: TOPBARVIEW

define('topbarView', [ 
    'backbone', 
    'parameterManager', 
    'text!views/topbarView/topbarTemplate.html', 
    'drupalidModel', 
    'weatherModel', 
    'refreshTime', 
    'dateParser' 
    ], function(Backbone, ParameterManager, TopbarTemplate, DrupalidModel, WeatherModel, RefreshTime, DateParser) { 

    var TopbarView = Backbone.View.extend({ 
     el: '#topbar', 

     template: _.template(TopbarTemplate), 

     events: {}, 

     initialize: function() { 
      var self = this; 
      _.bindAll(this, 'render', 'startDateRefresh'); 
      this.dateParser = new DateParser(); 
      self.startDateRefresh(); 
      setInterval(self.startDateRefresh, RefreshTime.date); 
      this.initWeatherModel();   
     }, 

     render: function() { 
      var self = this; 
      var data = { 
       picto_url : ParameterManager.get('WEATHER_RESOURCE_URL') + ParameterManager.get('WEATHER_PICTO_CODE') + ".png", 
       date: self.date 
      } 
      this.$el.html(this.template({data: data})); 
     }, 

     initWeatherModel: function() { 
      var self = this; 
      var weather_url = ParameterManager.get('WEATHER_URL'); 

      if(weather_url === null) { 
       this.drupalidModel = new DrupalidModel(); 
       this.drupalidModel.fetch({ 
        success: function(model, response) { 
         var center_id_num = model.get('center_id_num'); 
         ParameterManager.set('DRUPAL_CENTER_ID_NUM', center_id_num); 
         ParameterManager.constructWeatherUrl(); 
         self.model = new WeatherModel(); 
         self.listenTo(self.model,'change', self.render); 
         self.startModelRefresh(); 
        }, 
        error: function() { 
         console.log("Failed to fetch center id!"); 
        } 
       }) 
      } else { 
       this.model = new WeatherModel(); 
       self.listenTo(self.model,'change', self.render); 
       this.startModelRefresh(); 
      }; 
     }, 

     startModelRefresh: function() { 
      var self = this; 
      this.modelRefresh = function() { 
       self.model.fetch(); 
      }.bind(this); 
      self.modelRefresh(); 
      setInterval(self.modelRefresh, RefreshTime.weather);   
     }, 

     stopModelRefresh: function() { 
      var self = this; 
      clearInterval(self.modelRefresh); 
     }, 

     startDateRefresh: function() { 
      var self = this; 
      this.date = this.dateParser.classicDate(); 
      this.render(); 
     } 

    }); 

    return TopbarView; 

}) 
+2

'topbarView'には何がありますか? [mcve]を作成できますか? –

+0

これは、設定された間隔の悪い管理のためだと思うが、私は間違って何をしたのかを明確に理解することができない。 –

+0

私はMCVEのためにT Jの要求をもう一度。 Chromeデベロッパーツールでは、Timelineを使用してメモリ使用量を監視し、 'Collect garbage'(通常はゴミ箱アイコン)の規則を、特に' clean() 'を呼び出す前後に押します。 ifとwhat typeのメモリリークを分離する。これをあなたのポストに追加してください。バックボーンの誤用によるものではなく、簡単なクロージャのリークによってもメモリリークが発生する可能性があることに注意してください。 –

答えて

0

fbyniteが示唆したように、間隔(複数可)をクリアすることになってあなたのコードは、あなたがclearIntervalに間隔IDを渡す必要があり、正しくありません。

とは別に、stopModelRefresh()に電話することはありません。ビューを削除する前に、すべての外部参照が適切に削除されていることを確認する必要があります。たとえば、私は、ビューを削除する前に、間隔をクリアし、destroyメソッドを追加しました:

GhostviewHunter.prototype.clean = function() { 
    _.each(this.currentViews, function(view) { 
      view.destroy(); 
    }); 
    this.currentViews.length = 0; 
} 

またはあなたも上書きすることができます:

var TopbarView = Backbone.View.extend({ 
    el: '#topbar', 
    template: _.template(TopbarTemplate), 
    events: {}, 
    initialize: function() { 
    }, 
    render: function() { 
    }, 
    modelRefresh: function() { 
    this.model.fetch(); 
    }, 
    startModelRefresh: function() { 
    this.modelRefresh(); 
    this.intervalId = setInterval(_.bind(this.modelRefresh,this), RefreshTime.weather); 
    }, 
    stopModelRefresh: function() { 
    clearInterval(this.intervalId); 
    }, 
    destroy: function() { 
    this.stopModelRefresh(); 
    this.remove(); 
    } 

}); 

は、今すぐあなたのGhostviewHunterは直接removeを呼び出すのではなく、それを呼び出す必要があります

remove: function(){ 
    this.stopThisInterval(); 
    this.stopThatInterval(); 
    this.cleanUpSomethingElse(); 
    Backbone.View.prototype.remove.call(this); 
} 

とゴーストブツコールremoveがありますような何かにremove方法そのものそれ自体。あなたがさえクリアしようとしていないstartDateRefreshを呼び出し、他の間隔を持って


注...あなたは同様にこのようなすべてをクリアする必要があります。

そして、サイドノートとして、私は強く、それは例えばのために全く不要ですスパムself = thisを停止することをお勧め:

stopModelRefresh: function() { 
     var self = this; 
     clearInterval(self.modelRefresh); 
// Why..? Nothing here changes the context? 
}, 

と現在のフェッチが/ではなく、それを呼び出すよりも、失敗した成功したら、私はまた、再帰的にmodelRefreshを呼び出すことをお勧め以前のフェッチが完了しているという保証がない期間から

関連する問題