ExtJS4 内存泄漏
Posted
技术标签:
【中文标题】ExtJS4 内存泄漏【英文标题】:ExtJS4 memory leak 【发布时间】:2013-01-30 14:53:59 【问题描述】:我有一个用 ExtJS 4.1.1 编写的应用程序,它经常使用一个存储。我从服务器获取数据样本,经过一些验证后,我使用其“添加”方法将其添加到存储中。我这样做 我会定期从商店中删除我不需要的记录。
问题是,随着时间的推移,我的应用程序正在消耗越来越多的 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--;
但是当我在调试这个问题时检查控制台时,我可以看到,记录实际上是从存储中删除的,而不是从内存中删除的。
编辑/更新: 我尝试使用您的答案中的建议来解决问题,但都无法解决。可以肯定的是,我得到了正确的问题源,我提取了我的商店代码以更仔细地检查它,看看它是否真的导致了问题。您可以在下面看到整个代码:
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
);
);
现在奇怪的部分是:即使存储部分像上面的代码清单一样被注释,内存泄漏仍然存在。我是不是在任务管理方面犯了一些错误?
【问题讨论】:
【参考方案1】:我使用 Ext JS 发现的许多问题之一是 Ext.data.Model#destroy
实际上并没有在本地清理记录。 destroy
方法使用商店的代理发送对该记录的销毁请求(例如,如果您需要从数据库中删除相应的记录)。如果这是您的预期行为,那就不用担心。
当您从存储中删除记录时,该存储会在名为 removed
的数组中保留对该记录的引用。您可以在 Ext.data.Store#remove 方法的底部看到它。我建议使用 javascript 调试器并在删除几次后检查您的商店对象,以查看您的记录是否被缓存。如果是,只需调用store.removed.length = 0;
即可清除。
【讨论】:
我完全忘记了那个数组。 +1【参考方案2】:如果您在删除后执行store.sync()
会发生什么?不知道这是否有助于内存代理,但我认为它应该删除对已删除记录的引用。只是对记录执行remove(record)
并不会真正删除该记录,它只是将其标记为删除,并停止将其公开为在商店中可用。至少对于其他代理类型是这样。只有在通过store.sync();
同步了商店的修改记录(添加、删除、更新)后才能执行实际删除。这就是商店在其内部列表中保存新状态的记录的时候。
也许 sra 是正确的,而您自己在其他地方的闭包中持有对记录的引用?
【讨论】:
以上是关于ExtJS4 内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章