如何防止 Chrome 和 Firefox 长时间消耗大量内存?
How to prevent Chrome and Firefox from consuming vast amounts of memory over long periods of time?
我有一个用 JS 编写的长轮询应用程序获取 XML 文件来更新网页。它每 5 秒获取一次,大约 8KB 的数据。我已连续打开此网页大约 1 周(尽管计算机在晚上进入睡眠状态)。
第一次打开时 Chrome 它从我 PC 内存的大约 33K 开始。在我让它打开一个星期后,在 PC 处于唤醒状态时不断更新,仅一个选项卡就消耗了 384K。这是我的应用程序将 运行(让网页长时间打开)的常用方法。
我觉得我在阻碍 Chrome 的 GC 或没有进行某些特定的内存管理(甚至可能是内存泄漏)。我真的不知道如何在 JS 中实现内存泄漏。
我的应用程序范例非常典型,遵循这个无穷无尽的顺序:
function getXml(file){
return $.get(file);
}
function parseXml(Xml){
return {
someTag : $(Xml).find('someTag').attr('val'),
someOtherTag: $(Xml).find('someOtherTag').attr('val')
}
}
function polling(modules){
var defer = $.Deferred();
function module1(){
var xmlData = getXml('myFile.xml').done(function(xmlData){
var data = parseXml(xmlData);
modules.module1.update(data);
}).fail(function(){
alert('error getting XML');
}).always(function(){
module2();
});
});
function module2(){
var xmlData = getXml('myFile.xml').done(function(xmlData){
var data = parseXml(xmlData);
modules.module2.update(data);
}).fail(function(){
alert('error getting XML');
}).always(function(){
defer.resolve(modules);
});
});
return defer.promise(modules);
}
$(document).on('ready', function(){
var myModules = {
module1 : new Module(),
module2 : new ModuleOtherModule()
}
// Begin polling
var update = null;
polling(myModules).done(function(modules){
update = setInterval(polling.bind(this, modules), 5000);
});
这就是它的要点...我应该为像这样构建的应用程序做一些手动内存管理吗?我是否需要更好地管理我的变量或内存?或者这只是网络浏览器 (crome/ff) 打开 1-2 周的典型症状?
谢谢
您的代码似乎没问题,但您没有在 "modules" 中发布方法 "udpate" 上发生的事情。我为什么这么说?因为可能是那个方法泄露了你的应用程序。
我向你推荐两件事:
- 深入更新方法,看看你是如何更新DOM的(如果有很多节点要小心)。检查您正在更新的内容是否有关联的事件,因为如果您将事件侦听器分配给节点然后删除 dom 节点,您的侦听器仍保留在内存中(直到 javascript 垃圾收集器垃圾它)
- 阅读这篇文章。这是查找内存泄漏的最佳方法:https://developer.chrome.com/devtools/docs/javascript-memory-profiling
我有一个用 JS 编写的长轮询应用程序获取 XML 文件来更新网页。它每 5 秒获取一次,大约 8KB 的数据。我已连续打开此网页大约 1 周(尽管计算机在晚上进入睡眠状态)。
第一次打开时 Chrome 它从我 PC 内存的大约 33K 开始。在我让它打开一个星期后,在 PC 处于唤醒状态时不断更新,仅一个选项卡就消耗了 384K。这是我的应用程序将 运行(让网页长时间打开)的常用方法。
我觉得我在阻碍 Chrome 的 GC 或没有进行某些特定的内存管理(甚至可能是内存泄漏)。我真的不知道如何在 JS 中实现内存泄漏。
我的应用程序范例非常典型,遵循这个无穷无尽的顺序:
function getXml(file){
return $.get(file);
}
function parseXml(Xml){
return {
someTag : $(Xml).find('someTag').attr('val'),
someOtherTag: $(Xml).find('someOtherTag').attr('val')
}
}
function polling(modules){
var defer = $.Deferred();
function module1(){
var xmlData = getXml('myFile.xml').done(function(xmlData){
var data = parseXml(xmlData);
modules.module1.update(data);
}).fail(function(){
alert('error getting XML');
}).always(function(){
module2();
});
});
function module2(){
var xmlData = getXml('myFile.xml').done(function(xmlData){
var data = parseXml(xmlData);
modules.module2.update(data);
}).fail(function(){
alert('error getting XML');
}).always(function(){
defer.resolve(modules);
});
});
return defer.promise(modules);
}
$(document).on('ready', function(){
var myModules = {
module1 : new Module(),
module2 : new ModuleOtherModule()
}
// Begin polling
var update = null;
polling(myModules).done(function(modules){
update = setInterval(polling.bind(this, modules), 5000);
});
这就是它的要点...我应该为像这样构建的应用程序做一些手动内存管理吗?我是否需要更好地管理我的变量或内存?或者这只是网络浏览器 (crome/ff) 打开 1-2 周的典型症状?
谢谢
您的代码似乎没问题,但您没有在 "modules" 中发布方法 "udpate" 上发生的事情。我为什么这么说?因为可能是那个方法泄露了你的应用程序。 我向你推荐两件事:
- 深入更新方法,看看你是如何更新DOM的(如果有很多节点要小心)。检查您正在更新的内容是否有关联的事件,因为如果您将事件侦听器分配给节点然后删除 dom 节点,您的侦听器仍保留在内存中(直到 javascript 垃圾收集器垃圾它)
- 阅读这篇文章。这是查找内存泄漏的最佳方法:https://developer.chrome.com/devtools/docs/javascript-memory-profiling