【三】 Chrome的进程模型
1. 基本的进程结构
Chrome是一个多进程的架构,不过所有的进程都会由老大,Browser进程来管理,走的是集中化管理的路子。在Browser进程中,有xxxProcessHost,每一个host,都对应着一个Process,比如RenderProcessHost对应着RenderProcess,PluginProcessHost对应着PluginProcess,有多少个host的实例,就有多少个进程在运行。。。
这是一个比较典型的代理模式,Browser对Host的操作,都会被Host封装成IPC消息,传递给对应的Process来处理,对于大部分上层的类,也就隔离了多进程细节。。。
2. Render进程
先不扯Plugin的进程,只考虑Render进程。前面说了,一个Process一个tab,只是广告用语,实际上,每一个web页面内容(包括在tab中的和在弹出窗口中的...),在Chrome中,用RenderView表示一个web页面,每一个RenderView可以寄宿在任一一个RenderProcess中,它只是依托RenderProcess帮助它进行通信。每一个RenderProcess进程都可以有1到N个RenderView实例。。。
Chrome支持不同的进程模型,可以一个tab一个进程,一个site instance一个进程等等。但基本模式都是一致的,当需要创建一个新的RenderView的时候,Chrome会尝试进行选择或者是创建进程。比如,在one site one process的模式下,如果存在此site,就会选择一个已有的RenderProcessHost,让它管理这个新的RenderView,否则,会创建一个RenderProcessHost(同时也就创建了一个Process),把RenderView交给它。。。
在默认的one site instance one process的模式中,Chrome会为每个新的site instance创建一个进程(从一个页面链开来的页面,属于同一个site instance),但,Render进程总数是有个上限的。这个上限,根据内存大小的不同而异,比如,在我的机器上(2G内存),最多可以容纳20个Render进程,当达到这个上限后,你再开新的网站,Chrome会随机为你选择一个已有的进程,把这个网站对应的RenderView给扔进去。。。
每一次你新输入一个站点信息,在默认模式下,都必然导致一个进程的诞生,很可能,伴随着另一个进程的死亡(如果这个进程没有其他承载的RenderView的话,他就自然死亡了,RenderView的个数,就相当于这个进程的引用计数...)。比如,你打开一个新标签页的时候,系统为你创造了一个进程来承载这个新标签页,你输入www.baidu.com,于是新标签页进程死亡,承载www.baidu.com的进程诞生。你用baidu搜索了一下,毫无疑问,你基本对它的搜索结果很失望,于是你重新输入www.google.com,老的承载baidu的进程死亡,承载google的进程被构建出来。这时候你想回退到之前baidu的搜索结果,乐呵乐呵的话,一个新的承载baidu的进程被创造,之前Google的进程死亡。同样,你再次点击前进,又来到Google搜索结果的时候,一个新的进程有取代老的进程出现了。。。
以上现象,你都可以自己来检验,通过观察about:memory页面的信息,你可以了解整个过程(记得每做一步,需要刷新一下about:memory页面)。我唧唧歪歪说了半天,其实想表达的是,Chrome并没有像我YY的一样做啥进程池之类的特殊机制,而是简单的履行有就创建、没有就销毁的策略。我并不知道有没有啥很有效的多进程模型,这方面一点都没玩过,猜测Chrome之所以采取这样的策略,是经过琢磨的,觉得进程生死的代价可以承受,比较可行。。。
3. 进程开销控制算法
说开销无外乎两方面的内容,一为时间,二则空间。Chrome没有在进程创建和销毁上做功夫,但是当进程运行起来后,还是做了一些工作的。。。
节约工作首先从CPU耗时上做起,优先级越高的进程中的线程,越容易被调度,从而耗费CPU时间,于是,当一个页面不再直接面对用户的时候,Chrome会将它的进程优先级切到Below Normal的级别,反之,则切回Normal级别。通过这个步骤,小节约了一把时间。。。
进程的优先级 在windows中,进程是有优先级的,当然,这个优先级不是真实的调度优先级,而是该进程中,线程优先级计算的基准。在《Windows via C/C++》(也就是《windows核心编程》的第五版)中,有一张详细的表,表述了线程优先级和进程优先级的具体对应关系,感觉设计的很不错,我就不罚抄了,有兴趣的自行动手翻书。。。
|
当然这只是一道开胃小菜,满汉全席是控制进程的工作集大小,以达到降低进程实际内存消耗的目的(Chrome为了体现它对内存的节约,用了“更为精确”的内存消耗计算方法...)。提到这一点,Chrome颇为自豪,在文档中,顺着道把单进程的模式鄙视了一下,基本意思是:在多进程的模式下,各个页面实际占用的内存数量,更容易被控制,而在单进程的模式下,几乎是不能作出控制的,所以,很多时候,多进程模式耗费的内存,是会小于多线程模式的。这个说法靠不靠谱,大家心里都有谱,就不多说了。。。
具体说来,Chrome对进程工作集的控制算法还是比较简单的。首先,在进程启动的时候,需要指明进程工作的内存环境,是高内存,低内存,还是中等内存,默认模式下,是中等内存(我以为Chrome会动态计算的,没想到竟然是启动时指定...)。在高内存模式,不存在对工作集的调整,使劲用就完事了;在低内存的模式下,调整也很简单,一旦一个进程不再有页面面对观众了,尝试释放其所有工作集。相比来说,中等模式下,算法相对复杂一些,当一个进程从直接面对观众,沦落到切换到后台的悲惨命运,其工作集会缩减,算法为:TargetWorkingSetSize = (LastWorkingSet/2 + CurrentWorkingSet) /2;其中,TargetWorkingSetSize指的是预期降到的工作集大小,CurrentWorkingSet指的是进程当前的工作集(在Chrome中,工作集的大小,包含私有的和可共享的两部分内存,而不包含已经共享了的内存空间...),LastWorkingSet,等于上一次的CurrentWorkingSet除以DampingFactor,默认的DampingFactor为2。而反之,当一个进程从幕后走向台前,它的工作集会被放大为LastWorkingSet *DampingFactor * 2,了解过LastWorkingSet的含义,你已经知道,这就是将工作集放大两倍的另类版写法。。。
Chrome的Render进程工作集调整,除了发生在tab切换(或新页面建立)的时候,还会发生在整个Chrome的idle事件触发后。Chrome有个计时器,统计Chrome空闲的时长,当时长超过30s后(此工作会反复进行...),Chrome会做一系列工作,其中就包括,调整进程的工作集。被调整的进程,不仅仅是Render进程,还包括Plugin进程和Browser进程,换句话描述,就是所有Chrome进程。。。
这个算法导致一个很悲凉的状况,当你去蹲了个厕所回到电脑前,切换了一个Chrome页面,你发现页面一片惨白,一阵硬盘的骚动过后,好不容易恢复了原貌。如果再切,相同的事情又会发生,孜孜不倦,直到你切过每一个进程。这个惨案发生的主要原因,就是由于所有Chrome进程的工作集都被释放了,页面的重载和Render需要不少的一坨时间,这就大大影响了用户感受,毕竟,总看到惨白的画面,容易产生不好的情绪。强烈感觉这个不算一个很出色的策略,应该有一个工作集切换的底限,或者是在Chrome从idle中被激活的时候,偷偷摸摸的统一扩大工作集,发几个事件刺激一下,把该加载的东西加载起来。。。
整体感觉,Chrome对进程开销的控制,并不像想象中的有非常精妙绝伦的策略在里面,通过工作集这总手段并不算华丽,而且,如果想很好的工作的话,有一个非常非常重要的前提,就是被切换的页面,很少再被继续浏览。个人觉得这个假设并不是十分可靠,这就使得在某些情况下,产生非常不好的用户体验,也许Chrome需要进一步在这个地方琢磨点方法的。。。
相关推荐
"Chrome源码剖析系列" Chrome 源码剖析系列的目的是为了深入了解 Chrome 浏览器的源码结构和实现机制。通过对 Chrome 源码的剖析,我们可以了解到 Chrome 浏览器的架构设计、多进程模型、进程间通信机制、插件模型...
Chrome 源码剖析 Chrome 浏览器作为 Google 推出的一款革命性的浏览器,以其高效、稳定和安全的特点赢得了全球用户的青睐。它的设计和实现有许多值得深入研究的地方,包括多进程架构、V8 引擎、插件模型以及跨平台...
### Chrome源码剖析:多进程与多线程模型详解 #### 一、Chrome的多线程与多进程并发模型 ##### 0. Chrome的并发模型概述 Chrome浏览器因其独特的多进程架构而在众多浏览器中脱颖而出。根据给定内容,我们可以看出...
《深入剖析Android Chromium浏览器源码》 Android Chromium是一款开源的浏览器项目,它是Google Chrome浏览器在Android平台上的核心组件。此源码提供了深入了解Android应用程序开发、Web浏览技术以及Chrome浏览器...
c++应用电子书籍,独立打包,保证单包可解压,内含大量电子书,网上搜集而来,持续更新中...... 本包内容: ATL开发指南.pdf ATL_开发指南中文pdf_第二版.rar C++ 标准程序库 - 中文版.pdf ...Chrome源码剖析.doc
此外,Chrome开发者工具中的Profiler面板也可以提供深入的性能剖析。 9. **跨平台兼容性**: V8设计为跨平台的,可以在多种操作系统和硬件架构上运行,包括Windows、Linux、macOS和Android等,确保了在不同环境下...
这些组件具有良好的跨浏览器兼容性,支持主流的现代浏览器,如Chrome、Firefox、IE8及以上版本。 2. **源代码解析** 在压缩包中的"LigerUI"文件夹里,你会找到源代码文件,包括JavaScript文件和CSS文件。...
描述中的“已用npm处理过,已配置过源码文件,直接拿来用即可”,意味着Vue Devtools 3.1.5已经通过npm进行了预处理,无需用户自行编译源代码,简化了安装过程。只需将压缩包解压后导入Chrome浏览器的扩展程序管理...
CPU剖析器和内存剖析工具在这方面提供很大帮助。 7. **调试技巧**:熟练掌握条件断点、异常捕获、线程分析等高级调试技巧,可以极大提高源码追踪的效率。 8. **版本控制**:结合版本控制系统如Git,可以追踪代码的...
《深入剖析Zirco-Browser:Android开源浏览器的源码解析》 Zirco-Browser是一款基于Android平台的开源浏览器,其源码为我们提供了一窥移动浏览器内部运作机制的宝贵机会。通过研究这款浏览器的源码,我们可以学习到...
V8提供了性能剖析工具,如Chrome DevTools中的Profiler,帮助开发者定位性能瓶颈,优化代码。 通过深入理解V8引擎的工作原理,开发者可以编写出更加高效、更适合V8执行的JavaScript代码,从而提升应用程序的性能。...
本资料将带你深入探索Node.js的核心思想,并剖析其背后的libuv和V8引擎源码,帮助开发者更全面地理解这一技术。 一、Node.js核心思想 1. 单线程与事件循环:Node.js采用单线程模型,通过事件循环机制处理并发请求。...
本篇文章将围绕“Thinkphp游戏软件APP应用下载网站模板+前后端源码(带全部数据)”这一下载站源码展开讨论,从多个维度深入剖析其特点和适用性。 首先,从技术角度讲,该下载站源码基于Thinkphp框架开发。Thinkphp...
《深入剖析Chrome DevTools Timeline Model源码》 Chrome DevTools 是开发者们调试Web应用的得力工具,其中Timeline模块提供了一种可视化的性能分析界面,帮助我们了解网页在加载和运行过程中每一时刻的状态。...
本文将围绕“京东手机网站首页源码”这一主题,深入剖析其背后的网页设计原理、技术架构以及实现策略,旨在为开发者提供宝贵的参考。 一、前端框架与技术选型 京东手机网站首页的源码中,我们可以看到它采用了现代...