我有一个用ExtJS 4.1.1编写的应用程序,它经常使用一个商店。我从服务器获取数据样本,经过一些验证后,我使用“add”方法将其添加到商店。我这样做 我会定期删除商店中不需要的记录。
问题是,随着时间的推移,我的应用程序正在吃越来越多的RAM,似乎我找到了问题的根源,但我不知道如何处理它。
这是我的商店定义:
this.store = Ext.create('Ext.data.Store', {
fields: ['when', 'data1', 'data2', 'data3', 'data4', 'data5', 'data6', 'data7', 'data8', 'data9'],
proxy: {
type: 'memory',
reader: {
type: 'json',
root: 'users'
}
},
sorters: [{
property: 'when',
direction: 'ASC'
}]
});
这就是我从中删除记录的方式:
var record = self.store.getAt(j);
if((record.get('when') <= newMinDate) && (record.get('data'+id) !==' ')) {
self.store.remove(record);
record.destroy();
record = null;
j--;
ln--;
}
但当我在调试此问题时检查控制台时,我可以看到,记录实际上是从商店中删除的,而不是从内存中删除的。
EDIT / UPDATE: 我试图在你的答案中使用建议解决问题,但两者都无法解决。可以肯定的是,我得到了问题来源,我提取了我的商店代码,以便更仔细地检查它,看看它是否真的导致了问题。您可以在下面看到完整的代码:
Ext.define('TestApp.App', {
extend: 'Ext.app.Application'
});
Ext.application({
extend: 'MyApp.app.Application',
store: null,
launch: function() {
var self = this;
self.store = Ext.create('Ext.data.Store', {
fields: ['when', 'data1', 'data2', 'data3', 'data4', 'data5', 'data6', 'data7', 'data8', 'data9'],
proxy: {
type: 'memory'
},
sorters: [{
property: 'when',
direction: 'ASC'
}]
});
self.beginTask();
},
beginTask: function() {
var self = this;
Ext.TaskManager.start({
run: function() {
var jsonRaw = *very large json*; //about 650 samples
var json = Ext.JSON.decode(jsonRaw, true);
// self.store.add(json.data.samples);
// var ln = self.store.getCount();
// for (var j=0; j<ln; j++) {
// var record = self.store.getAt(j);
// self.store.remove(self.store.getAt(j));
// j--;
// ln--;
// record.destroy();
// delete record;
// }
json = null;
jsonRaw = null;
},
interval: 1000
});
}
});
现在关于这个的奇怪部分:即使商店部分被注释,如上面的代码清单中也存在内存泄漏。我在任务管理方面犯了一些错误吗?
答案 0 :(得分:5)
我使用Ext JS发现的众多问题之一是Ext.data.Model#destroy
实际上并没有在本地清理记录。 destroy
方法使用商店的代理发送该记录的销毁请求(例如,如果需要从数据库中删除相应的记录)。如果这是你的预期行为,那就不用担心了。
从商店中删除记录时,该商店会在名为removed
的数组中保留对该记录的引用。您可以在Ext.data.Store#remove方法的底部看到它。我建议使用JavaScript调试器并在几次删除后检查您的商店对象,以查看您的记录是否正在被缓存。如果是,那么就可以通过调用store.removed.length = 0;
来清除它。
答案 1 :(得分:0)
如果您在删除后执行store.sync()
会怎样?不知道这对内存代理是否有帮助,但它应该删除对我认为删除的记录的引用。只是在记录上执行remove(record)
并没有真正删除记录,它只是将其标记为删除并停止在商店中公开它。对于其他代理类型,至少这是真的。只有在通过store.sync();
同步商店的修改记录(添加,删除,更新)后,才能执行实际删除。当商店将记录保存在其新状态的内部列表中时。
也许sra是正确的,你自己在其他地方的封闭中持有对该记录的引用?