我注意到在使用firefox几个小时之后它会获得更多的2GB ram内存。特别是当我使用ajax上传器上传大文件(100mb-400mb)时,以及当我打开许多图像时(例如网页上的总图像数为16mb),也会发生这种情况。
问题是即使在上传完成后或关闭图像页面后内存也没有获得释放,Firefox仍然有2GB的内存。 有没有办法让javascript让firefox释放内存,例如上传完成后或加载或关闭图片后?
修改
来自about:memory
:
1,172.03 MB(100.0%) - 显式
├──1,000.00MB(85.32%) - js
│├────863.97MB(73.72%) - 隔间([系统主体],0x5083000)
││├──819.31MB(69.91%)──string-chars
我如何清空 string-chars ,我很确定当文件被重新加入内存然后使用ajax上传时会出现这种情况?
编辑2
以下是导致此内存使用的recrusive函数:
function uploadAjax(file, startByte, index)
{
if(startByte==0)
{
$('#progress'+index).html(' ').progressbar( "destroy" ).progressbar();
$('#asyncuploadsingle'+index).attr('disabled', true);
}
var size = file.size;
var chunkSize = 2097152;//2 megabyte
var endByte = chunkSize + startByte;
var isLast = (size - endByte <= 0);
var chunk = file;
var xhr = new XMLHttpRequest();//prepare xhr for upload
var chunkNum = endByte / chunkSize;
if(chunkSize == 0)//no divide
{
chunk = file;
isLast = true;
}
else if(file.mozSlice) // moz slice
{
chunk = file.mozSlice(startByte, endByte);
}
else if(file.webkitSlice) //webkit slice
{
chunk = file.webkitSlice(startByte, endByte);
}
else if(file.slice) // w3c slice
{
chunk = file.slice(startByte, chunkSize);
}
else
{
chunk = file;
isLast = true;
}
//progress function, with ajax upload progress can be monitored
xhr.upload.addEventListener('progress', function(e)
{
if (e.lengthComputable)
{
var perc = Math.round((e.loaded + chunkNum * chunkSize - chunkSize) * 100 / size);
//console.log(perc+':'+index);
$('#progress'+index).progressbar("option", "value", perc);
}
}, false);
xhr.upload.onabort=function(e) {
finishUp(index,'Aborted');
};
xhr.upload.addEventListener('error', function(e){
finishUp(index, this.responseText+'--->'+name);
}, false);
xhr.onreadystatechange=function()
{
if(this.readyState == 4 && this.status == 200)
{
try
{
var ret = JSON.parse(this.responseText);
if(isLast)
{
finishUp(index,'');
}
else if(ret.status == 'error')
{
throw ret.info;
}
else
{
uploadAjax(file, endByte, index);
}
}
catch(err)
{
finishUp(index, err);
}
delete chunk;
}
};
var path = get_final_path();
var url = "filetransfer/uploadfiles.php?ax-file-name="+encodeURIComponent(file.name)+"&ax-file-path="+encodeURIComponent(path)+'&ax-start-byte='+startByte;
xhr.open("POST", url, true);
xhr.setRequestHeader('Cache-Control', 'no-cache');
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');//header
xhr.setRequestHeader('Content-Type', 'application/octet-stream');//generic stream header
/*var reader = new FileReader();
reader.onload = function(evt) {
xhr.sendAsBinary(evt.target.result);
};
reader.readAsBinaryString(chunk);
*/
xhr.send(chunk);
return xhr;
}
在哪里优化它或在何处释放物体?
答案 0 :(得分:2)
我使用Memoryfox插件将firefox的内存保持在最低限度。虽然我只将其用于浏览器(不启用“所有进程”选项),因为我经常运行Photoshop / Lightroom并且它会在所有进程模式下干扰它们(它非常激进)。
虽然即便如此,Firefox仍然会膨胀。最好的方法是删除任何不使用的插件,并禁用那些不经常使用的插件。如果你有很多插件,有一些会导致firefox出现重大内存问题,其中一些会在MemShrink project下突出显示。
具体参考编辑中提供的代码,有几个原因导致您可能会看到额外的内存使用情况:
1)使用匿名函数意味着每次运行uploadAjax时,每个内存都会为内存创建一个新函数。在uploadAjax之外定义你的函数然后引用它们以避免重复内存。
2)delete xhr;
当你完成它。它通常不是必需的,但是如果你进行大量的上传,可能会留下一些东西。
3)你实际上是在递归和匿名函数内部调用uploadAjax(file, endByte, index);
,这意味着你在较高级别调用中创建的所有内容可能仍然存在,而较低级别的调用执行。这将导致多个内存中xhr
和chunk
。考虑以不同的方式调用uploadAjax
(例如通过触发事件然后从全局或短计时器访问同一文件和xhr以便引入执行断开连接。我可能更喜欢前者如果不自己测试,很难说肯定。)
答案 1 :(得分:1)
这不是你想要的,但听起来这就是你所需要的:
https://addons.mozilla.org/en-US/firefox/addon/memory-restart/
您可以为警报设置阈值,甚至可以自动重启。
(虽然,正如我刚刚发现Rob W的礼貌,about:memory
允许你进行垃圾收集并进行其他内存清理(至少在Firefox 13中;没有检查它在多远在这台机器上没有以前版本的Firefox,我没有时间下载和安装以前的版本进行测试。非常简洁。你可能想先尝试使用它,即使它不是自动的,如果自动 - 重新启动Firefox不是你喜欢的。)
答案 2 :(得分:0)
这是firefox背后发生的最糟糕的事情......我曾经也遇到过这个问题。问题是你必须重新启动你的浏览器,所以一些内存将是免费的,但不是全部。这是One Page Application的主要问题,主要是在没有刷新页面的情况下使用dom替换。
答案 3 :(得分:0)
firefox中没有javascript API来帮助解决您的问题。尽管需要做大量工作来改善足迹,但Firefox中的内存使用量一直是最长期的抱怨之一。您的选择主要限于:
(a)重启firefox以杀死进程并释放它的已分配内存
(b)使用Firefox或Windows的第三方实用程序或插件来帮助释放其部分内存
(c)使用其他浏览器,例如Chrome,它使用每个标签的流程模型,有助于缓解内存使用问题