Backbone.js 主干内存泄漏删除不工作?
在路由器中,我这样做Backbone.js 主干内存泄漏删除不工作?,backbone.js,memory-leaks,Backbone.js,Memory Leaks,在路由器中,我这样做 function test() { self.topbarView = new TopbarView(); self.topbarView.render(); GhostviewHunter.addView(self.topbarView); } function clean() {
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();
})
TopView正在获取模型,该模型每1秒使用setInterval函数更新一次
我以为那是我的错;当我监视应用程序时,内存泄漏很快就足够了
有什么想法吗
编辑:
顶视图
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;
})
正如fbynite所建议的,您应该清除间隔的代码不正确,您应该将间隔id传递给
clearInterval
除此之外,您根本不需要调用stopModelRefresh()
。在删除视图之前,应确保已正确删除所有外部参照。例如,我添加了一个销毁方法,在删除视图之前清除间隔:
var-TopbarView=Backbone.View.extend({
el:“#顶杆”,
模板:u.template(TopbarTemplate),
事件:{},
初始化:函数(){
},
render:function(){
},
modelRefresh:function(){
this.model.fetch();
},
startModelRefresh:function(){
这个.modelRefresh();
this.intervalId=setInterval(u.bind(this.modelRefresh,this),refreshttime.weather);
},
stopModelRefresh:function(){
clearInterval(此为有效期);
},
销毁:函数(){
此参数为.stopModelRefresh();
这个。删除();
}
});
现在您的GhostviewHunter
应该调用它,而不是直接调用remove
:
GhostviewHunter.prototype.clean = function() {
_.each(this.currentViews, function(view) {
view.destroy();
});
this.currentViews.length = 0;
}
或者您甚至可以将remove
方法本身重写为如下内容:
remove: function(){
this.stopThisInterval();
this.stopThatInterval();
this.cleanUpSomethingElse();
Backbone.View.prototype.remove.call(this);
}
然后让鬼魂呼叫移除它自己
请注意,您还有其他间隔调用startDateRefresh
,您甚至都没有尝试清除它。。。你应该同样地清除所有这些
另外,我强烈建议停止在完全没有必要的情况下发送垃圾邮件,例如:
stopModelRefresh: function() {
var self = this;
clearInterval( self.modelRefresh );
// Why..? Nothing here changes the context?
},
我还建议在当前提取成功/失败后递归调用modelRefresh
,而不是在无法保证前一次提取完成的时间间隔内调用它。。?你能创建一个吗?我想这是由于设置间隔管理不善造成的,但我不能清楚地指出我做错了什么我支持TJ的MCVE请求。在Chrome developer工具中,使用Timeline来监控内存使用情况,并定期按收集垃圾(通常是垃圾桶图标),尤其是在调用clean()
前后。隔离内存是否泄漏以及泄漏的类型。将此添加到您的帖子中。请注意,内存泄漏可能不是由主干误用引起的,而是由一个小的关闭泄漏引起的。在startModelRefresh
中,您启动了许多setInterval
,但没有正确清除它们setInterval
返回用于clearInterval
的id。目前,在stopModelRefresh
中,您正在传递一个函数引用。我会先解决这个问题。