阅读:14462回复:84
关于内存使用的疑问
偶然接觸了一個超大网页后才发现的。这里是小圆脸的一个考据贴。不完全保存下来后有58M的样子
http://www.gcforum.org/viewthread.php?tid=5721 保存下来后,用浏览器打开,奇妙的事情发生了 IE9 :很奇怪的不知道为什么阻挡了图片,不好作为对比,弃权 Firefox 4.0.1 (29扩展) : 内存占用如第一张附图 Firefox 6a1 (无扩展) :内存占用用第二张附图 Chromium(12): 内存占用如第三张附图 从图可见,无论有没有扩展,firefox的内存占用在加载网页后极具增长,我的内存已经不够以至于被削尖了……剩下的塞到虚拟内存去了,实际的占用甚至远远大于这个值。而且可以看见增长速度非常惊人,在拖拽网页后,从正常的200M猛增到1G多…… 而Chrome几乎没什么内存变动…… 从效果上而言,二者基本相同,所有的图片,文字,样式都是完整显示的。 我奇怪的是,为什么一个总量58M的网页会需要那么多内存显示?为什么chrome又不需要?机理是啥?然后我以为是某个插件的问题,于是拿纯净版的Fx6测试,结果内存依然飙升……参见图三中的两个尖峰…… 是我不小心设置了什么地方吗? 然后我最想问的还是,为什么一个58M的网页需要上G的内存来显示…… [s]如果有必要的话,我可以把已保存的网页上传来测试……就是那个58M的……[/s] *edit* 上传了,大家可以自己试试打开这个网页不同浏览器占用的内存……另外测试前先保护好你的重要网页,firefox基本一定会崩的…… http://u.115.com/file/f0bec6fb08 |
|
|
1楼#
发布于:2011-04-28 10:37
|
|
|
2楼#
发布于:2011-04-28 10:37
lord:试试这几个选项,看看有没有改善 参见这个帖子https://g.mozest.com/thread-38497-1-1 都没用。因为现在的问题是一加载页面Firefox就立刻开始读取,和解码与否关系不大 第一个只是开关是否丢弃(默认开启),第二个是改变解码时机,第三个是超时时间,只决定未显示的图片丢弃的时间而已。改为100ms后测试结果如图,在两个tab间切换时的内存简直是…… 只要我还停留在那个tab,内存占用就不会像chrome那样低 如果连接到原始帖子,chrome的做法是只下载,不解码也不读取(?),内存毫无变动,随着浏览的进行才会把图片加载到内存中。而firefox则是全部加载,大量内存被分配给根本看不到的部分,这样不合理吧- - |
|
|
3楼#
发布于:2011-04-28 10:37
re lord
仔细想了想,discard时间应该影响不大,但是decodeondraw应该正是我所需要的!但是改了之后没效果(当然重启过),一载入网页还是一下子就全部decode, 把内存占满了… |
|
|
4楼#
发布于:2011-04-28 10:37
|
|
|
5楼#
发布于:2011-04-28 10:37
|
|
|
6楼#
发布于:2011-04-28 10:37
测试了一下,载入网页时二者都是慢慢内存升高,如温水煮青蛙,对比意义不大
【附图A】 (话说咱论坛怎么插附件图 下面是载入本地保存页面的结果 Firefox4.0.1 【附图B】 第一图Fx是一开始就decode了本页所有图片然后塞入内存,可见内存占用非常高,注意下方的提交,虚拟内存已经到上限了…… 第二图是上下拖动,保证所有图片都decode后测试网页的最大内存占用,惊人的储存空间占用…… 第三图是关闭后的效果 Chromium 12 【附图C】 第一图最左边是Cr刚载入的时候,内存占用可以忽略,可以肯定只decode了当前屏幕,或者几个屏幕的图片,右边是刚开始以较快速度使用中键浏览模式移动,在第一次到1G内存的时候出现了一个奇怪的释放,之后我使用按住滚动条快速卷动,直到底部,之后没有出现释放。此时内存占用没有达到最大值 第二图是上下卷动,确保所有图片都已经decode,内存占用不再增加后的最大内存占用值。虽然提交数要比firefox小近1个G,但是进程选项中显示值和firefox差不多,1.6G 第三图是关闭后的内存。 结果分析: 最大载入状态下,二者的内存占用都是1.5G左右,这是和网页相关的一个属性,所以可以看出,要完整显示整个网页,除了增加内存别无他法。虽然提交大小chrome比Firefox小近1G,不过这说明不了什么问题。 而Chrome的decodeondraw只在第一次载入的情况下生效,一旦浏览完整个网页,内存占用只比Fx4小500M~1G左右,原因是第一次占用到1G时意味不明的释放行为。 整体浏览行为对比(有实验支撑) 消歧义: 内存 - 指性能页左边显示的绿条,代表物理内存的占用情况 提交 - 性能页右下角的提交显示,其值=物理内存+虚拟内存,代表程序运行所需的线性储存空间 Fx4: *首次读取:读入整个网页,decode所有图片(理由是内存飚增,性能页的提交涨到3G左右)。 *浏览过程:在浏览过程中内存(进程页)显示不变,1.5G左右,但是性能页的提交会随着浏览渐渐增加(特别的,当第一次内存到1G左右时会有一个释放行为,参见图片,其后没有) *完全加载:完全浏览完页面,提交最终涨到4.2G左右……(- -|||)并且随时间推移不会释放 *切换tab:切换tab时不释放,直到达到设定的discard时间(默认2分钟),或者有恢复关闭页面。 *关闭tab:关闭tab时纯洁profile的行为未知,有恢复关闭页面扩展的情况下不释放。 Chromium12: *首次读取:读入当前屏幕和整个网页的非多媒体部分(如js等),不会decode其他部分的图片(理由是内存几乎没有变化) *浏览过程:在浏览过程中内存和提交随着浏览进程升高,在第一次达到1G的时候会有一个释放行为(见图中的折线),然后一路涨到最高值 *完全加载:完全浏览完页面,提交最终涨到3G左右……随时间推移不会释放(slimx所说的不会降下来) *切换tab:切换tab时立即释放所有提交。再次切换回来时重新开始首次读取的行为,即浏览到的地方才decode。也就是说,除非你一直停留在此界面浏览,否则只要有一次切换tab的行为就不会导致内存达到最大值(比如Fx惊人的4.2G……) *关闭tab:关闭tab时纯洁profile完全释放提交和内存 结论: 就图片性能管理这一方面个人感觉Firefox完全没有Chromium做得好。 首先从性能分析上讲,Firefox从第一次载入页面后就会一直处于最大内存占用情况,并且在载入或者一段时间后切换标签过去的一瞬间会有非常迅速的内存暴涨过程,这样的冲击对于程序稳定性是非常不利的,很可能造成失去响应或者崩溃。而chrome的理念则是实时加载,一有机会就释放,保证低内存的情况下正常显示所有图片。并且,一旦切换标签就释放所有decoded数据,虽然听起来好像挺笨。但是实际上,decode的速度是非常快的,从Fx首次载入全部图片那一刻就能看出来,decode1.5G的图片塞满你的内存只需要几秒,考虑到内存速度,瓶颈可能还不是decode本身,而是写入内存。至少在我的机器上,chrome实时decode从未出现图片延迟显示的情况,即使按住滚动条急速卷动——只有内存在飚而已 然后从浏览体验上讲,一个页面一打开就失去响应,另一个页面立刻就显示,而且二者浏览时没什么大区别,显然后者更流畅。不光是已保存网页,哪怕是实时载入网页,你总会切到其他tab干别的事等待载入吧,而chrome切换即释放的特性保证在这个过程中内存一直处于低水平。注意是释放decode数据,图片本身还在内存里,不牵涉到虚拟内存效率,更不牵涉到硬盘IO,就效率上讲,没有什么劣势。 我最不能理解的是,如果Fx预先decode了页面所有图片,为什么浏览时提交还会疯长?以至于最后同样的页面涨到4.2G提交,比chrome多1.2G……把我的内存+虚拟内存全部吃完了…… 当然没有用纯洁的profile测试是我的失误,这1.2G的差别有可能是扩展的问题。 不管是不是扩展的问题……总之Fx这样一口气吞掉的行为相当于一个冲击,对稳定性是非常不利的。切换tab释放就不要求了,因为这是恢复关闭页面的必然代价。现在就希望能看一点给我decode一点,不要像默认大家都是4G内存一样一下子就把整个页面吃下去(而且浏览过程中提交还会涨……不知道为什么…… |
|
|
7楼#
发布于:2011-04-28 10:37
|
|
|
8楼#
发布于:2011-04-28 10:37
如果有必要的话,我可以把已保存的网页上传来测试……就是那个58M的…… 一小时是个概述,明显这个和你的网速有关。 如果我没有明确说明是完全载入后那还真是抱歉了,我以为一般人不会用刚打开的数据来测试呢 其次,我提到过 Fx4: *首次读取:读入整个网页,decode所有图片(理由是内存飚增,性能页的提交涨到3G左右)。 *浏览过程:在浏览过程中内存(进程页)显示不变,1.5G左右,但是性能页的提交会随着浏览渐渐增加(特别的,当第一次内存到1G左右时会有一个释放行为,参见图片,其后没有) *完全加载:完全浏览完页面,提交最终涨到4.2G左右……(- -|||)并且随时间推移不会释放 *切换tab:切换tab时不释放,直到达到设定的discard时间(默认2分钟),或者有恢复关闭页面。 *关闭tab:关闭tab时纯洁profile的行为未知,有恢复关闭页面扩展的情况下不释放。 至于你的8小时,相信firefox还不会呆到一直不释放,当然,没有测试,我无法确定。 最后,你究竟有没有仔细看的实验数据?鄙人认为,所谓危言耸听是在没有根据的情况下蓄意夸大事实以获得关注的行为,现在实验数据就摆在你面前,不说每个人都这样,起码在我这里事实如此,何来危言耸听之说? 其次,我说的4.2G是显示值,下面也明确指出关闭浏览器后的剩余量,其差值才是Fx的整体占用,难道又被你无视了? 整体浏览行为对比(有实验支撑) 消歧义: 内存 - 指性能页左边显示的绿条,代表物理内存的占用情况 提交 - 性能页右下角的提交显示,其值=物理内存+虚拟内存,代表程序运行所需的线性储存空间
这句话我不知道你是在自嘲还是怎样,我是一个工程师,我只相信实验结果,其他一律是放屁。 至于是否是Fx本身的原因,或者是其他问题,哪些是实验数据之后的分析步骤,很明显我们现在只是在陈述现象,希望你不要看见一点有悖你的价值观的东西就跳出来喧嚣,无论对错,只要是有根据的指责我都接受,没有根据的我一律当做放屁 |
|
|
9楼#
发布于:2011-04-28 10:37
|
|
|
10楼#
发布于:2011-04-28 10:37
那还真是委屈你了,认真的测试者。我们结果的不同只是因为你没有看见“完全载入”四个字而已。然后你拒不承认这个简单的错误,导致现在下不了台,值得么
当然,我没有用加粗红色大号字体标明测试条件是我的失误,不过在你之前有很多狐友“意会”了我的前提条件,导致我以为大家都能理解。 所以你现在可以下载我亲自上传的附件,然后把那个该死的htm丢掉你的火狐子里去,然后我们的测试条件就一样了。如何? |
|
|
11楼#
发布于:2011-04-28 10:37
说道最后你还是没有下载我的附件罢。
|
|
|
12楼#
发布于:2011-04-28 10:37
huhuhu:昨天看了看javascript,现学现用写了一个简单的测试网页,就是多图的页面的读取。我的想法是把一个多图网页存成本地文件,然后用FF以幻灯片形式一张一张播放图片(间隔500ms)。相当于我们经常用的滚屏看图吧,有两种方式读取。一种是网页加载时预读所有图片,然后播放。还有一种是不预读实时解码播放。图片就是本帖网页的那些图。我取了300张。测试结果如下: 赞测试,这么看来fx3.6确实是如大家所说,内存管理方便没有释放的情况 我的理念是,未解码的图像通常是jpg,体积不会很大,因此应该优先缓存到内存中。而解码后的图片是原始格式,总量可能非常大,因此应该实时释放。 考虑到恢复关闭标签页的功能,如果可以将未解码数据存到内存/磁盘缓存中(也就是恢复标签所用缓存),那么就不矛盾了:可恢复的数据只是未解码的图像,比如那个考据贴,即使可以恢复,也只会占用60M空间而已,考虑到页面架构等,应该不会超过200M占用。作为可恢复的代价是可接受的(而不是现在这样1G多) 此外,你提到:“3:Nightly预读所有图片,打开网页后内存峰值达到1G左右,预读完后无任何变化还是1G,播放时内存略微增加。” 不光要看内存,因为win7显示的只是物理内存,应该更多的关注右下角的提交大小,那是真正占用的线性储存空间的指标。在我这里,浏览的过程中增加的提交大小和预读时瞬间增长的大小几乎相同(考虑到你只用了300图片,300-500,1G-1.3G,可以认为我们的效果是等价的),因此我猜测,在你浏览的过程中,虽然物理内存没有变化(有波动,或许就是你说的略微增加),但是提交大小还是又增长了一倍。 也就是我的疑惑:第一次大量的数据是在预读什么?解码图片并放入内存?那么浏览过程中增长的内存又是什么?再解码一次放入内存? Chrome在浏览的过程中也会增长占用,总的大小和firefox相仿,和Fx区别就是没有刚打开时的那个1.3G的预读 |
|
|
13楼#
发布于:2011-04-28 10:37
非常感谢你的代码,我不会html或是js,就改了一下你的代码
但是你的测试并不能完全代表浏览行为。我认为,一般的浏览行为可以分为两种: 1. 一边浏览一边下载 (Fx:内存越来越大直到死掉 Cr:内存同样越来越大) 2. 打开已保存网页(Fx:你们懂的 Cr:毫无压力) 不过,通过你的测试我发现了一个有趣的行为对比…… 请看附图。所用代码: 预读 <html> <head> <script type="text/javascript"> aimg =new Array; for(i=0;i<495;i++){aimg[i]=new Image();aimg[i].src="file:///Q:/Down/t/"+i+".jpg"}//预读图像 var c=0 var t function timedCount() { var w= window.open(aimg[c].src,"test","chrome,width=800,height=600"); c=c+1 t=setTimeout("timedCount()",100) if(c>494){clearTimeout(t);w.close()} } </script> </head> <body> <form> <input type="button" value="Start" onClick="timedCount()"> </form> <p>开始播放(已预读)</p> </body> </html> 不预读 <html> <head> <script type="text/javascript"> aimg =new Array; var c=0 var t function timedCount() { aimg[c]=new Image();aimg[c].src="file:///Q:/Down/t/"+c+".jpg" //不预读图像 var w= window.open(aimg[c].src,"test","chrome,width=800,height=600"); c=c+1 t=setTimeout("timedCount()",100) if(c>495){clearTimeout(t);w.close()} } </script> </head> <body> <form> <input type="button" value="Start" onClick="timedCount()"> </form> <p>开始播放(未预读)</p> </body> </html> 测试前均完整清楚双方的缓存,关闭无关程序。Fx4预读测试前面的内存波峰请不要在意,那是代码写错后导致崩溃了- - 分析结果: *firefox要浏览完所有图片,无论是否预读,总是需要接近2.5G的空间,预读时只是首先分配一部分,另一部分在浏览时分配 *Chrome的预读与不预读没什么区别……而且在整个过程中内存/提交展现出惊人的稳定性……太平公主 结论: *Fx4预读的情况下内存释放效果略差(当然也可能只是实验顺序的关系,不过没精力做多次取平均值了) *Chrome的结果让人震惊,不知道是Cr有识别本地图片的功能还是一边解码一边释放(因为在代码中是使用新窗口显示,根据前面的分析,切换tab和新窗口时chrome是会释放资源的) *测试中用过几个延时,发现无论是否预读,快速浏览时都很卡,会有停顿。慢速时则毫无差别。无论是否预读,还是chrome一样实时解码,cpu占用都很低(大概在25%作用),即使是老机器应该也毫无压力。其次,如果延时低于50ms,无论是否预读,Fx4都几乎一定会崩溃……Chrome调到10ms都没问题(但是cpu占用到80%+) 所以,就目前的情况看来,预读是毫无必要的,除了白白占用内存乃至虚拟内存,对浏览流畅性,快速性都没有任何提升。 |
|
|
14楼#
发布于:2011-04-28 10:37
更夸张的是
Fx4 不预读:播放时硬盘灯不闪,而是一直亮着= = 而且播放速度过快会崩溃,即使间隔100ms,期间也出现了4次停顿 预读:预读时闪了一下(并且预读过程很可能崩溃),播放过程中硬盘灯一直闪,频率非常高,同样有停顿,间隔不能太低 Chrome 不预读:播放时硬盘灯一直闪,频率比预读的Fx略低,即使间隔10ms也完全流畅 预读:预读时硬盘灯闪一下,播放过程中几乎完全不闪(!),同样播放完全流畅 也就是说,chrome的缓存管理就是我所期待的,把未解压的数据放到内存中,显示时实时解码。尤其是预读的chrome,不但预读快,不占内存,而且显示时释放及时,硬盘完全休息!! 而Fx不完全的预读,预读占用内存惊人就惊人吧,好歹起点作用啊,显示过程中硬盘灯还是闪成狗了是怎么回事啊! 窃以为,Fx是按照弱cpu开发的,以内存空间换性能,而chrome则以高速cpu为前提,减少内存占用。就我的AMD X2 245而言,在100ms播放时二者的cpu占用差不多都是25%,10ms时Fx4崩溃,Cr占用75%~80%。而10ms是最极端的情况吧,通常的正常浏览,每秒5张图已经是达人级了,所以,实时解码几乎不会对浏览造成影响,反倒是内存占用太大,不得不丢虚拟内存时,硬盘和内存之间的数据交换才成为瓶颈(Fx的播放过程各种卡顿) 就这一项,我认为Mozilla完全输给google了……赶快在Firefox5里加入更牛逼的管理把google比下去啊混蛋! |
|
|
上一页
下一页