chrome进程架构

来源:互联网 发布:魔音变声软件 编辑:程序博客网 时间:2024/05/22 01:42

多进程构架

该文档描述chromium的定层架构。

问题

 建一个永不崩溃和阻塞的渲染引擎(rendering engine )几乎是不可能的。同样,做一个绝对安全的渲染引擎也是不可能的。

 从某种意义上说,目前web浏览器的状况有点像过去的单用户,多任务的操作系统。应用的误操作会导致整个系统的崩溃。类似,现在的web浏览器中的网页误操作会导致整个web浏览器崩溃。浏览器或插件引入bug会导致整个浏览器崩溃,而且所有的正在运行的浏览标签也随之而去。

现在操作系统比原来的健壮多了,因为它把各个应用放到了隔离的进程中,一个应用的崩溃,不会导致其他进程的崩溃,更不会威胁到操作系统。并且,一个用户操作另一个用户的数据的行为也做了限制。

体系概览

 我们为每个浏览器的标签设置了独立的进程。用以保护应用程序不受bug和失败的渲染引擎的影响。我们也限制渲染引擎之间互相访问,也限制它访问系统的其他部分。从某种意义说,web浏览器受益于操作系统中的内存保护和访问控制的成功经验。

我们把运行UI,管理tab(标签)和插件的进程称为“浏览器进程”(browser process)或“浏览器”,同样的,指定的tab进程称为“渲染进程”(render process)或“渲染器”。渲染器使用开源的webkit布局引擎来解释和布局HTML。

渲染进程的管理

每个渲染进程有一个全局的RenderProcess 对象来维护全局状态,并且与父浏览器进程通信。浏览器也相应的为每一个渲染进程维护一个RenderProcessHost,用来管理浏览器状态,并且与渲染器通信。浏览器与渲染器的通信使用的是chromium的IPC系统。

视图的管理

每个渲染器都有一个或多个RenderView对象(渲染视图对象),由渲染进程管理。渲染视图与标签的内容对应。相应的有RenderProcessHost 维护一个RenderViewHost与渲染器中的视图对应。每个视图都有一个视图ID用来区分同一个渲染器的不同视图。这些id在同一个渲染器中唯一,但是在浏览器中则有可能不唯一。所以,(针对浏览器)标识一个视图需要RenderProcessHost 和一个视图ID才行。浏览器到视图中的任何消息都要通过RenderViewHost 传递。如何通信,上面已经描述了。

组件与接口

在渲染进程中:

  • 渲染进程(render process)持有与浏览器中RenderProcessHost 对应的IPC,每个RenderProcess 都有的对象。于是browser ↔ renderer 通信就能发生了。
  • 渲染视图(RenderView)与浏览器中RenderViewHost 通信(当然要通过渲染进程),同时,webkit也嵌入其中。该对象表示标签网页中的内容和弹出窗口。

在浏览器进程中:

  • 浏览器对象表示浏览器的顶层窗口。
  • RenderProcessHost 对象表示一条browser ↔ renderer IPC 连接中的浏览器通信端。浏览器为每个渲染器均有一个RenderProcessHost 对象。
  • RenderViewHost 对象封装了与RenderView远程通信,RenderWidgetHost 处理浏览器中RenderWidget 的输入与绘制
更对详细信息与工作细节,参见How Chromium displays web pages设计文档。

Sharing the render process
渲染进程间的共享

在通常情况下,每个新窗口或新标签都会打开一个新的进程。浏览器会启动新进程并且指导他建立一个单一的渲染视图。

有时候,有可能,甚至是必须的,标签或窗口间需要共享一个渲染进程。web应用打开一个新的窗口,并且期望能同步的进行通信。例如,使用javascript的Windows.open。在这种情况下,当我们常见新的窗口或标签,就需要重用已经打开的窗口的进程。同样,我们也有这样的策略,如果进程总数过大,我们也会将新的标签赋予已经存在的进程。或者用户已经打开该域名的网站,这个策略在进程模型的有描述。

检测崩溃和渲染器的错误操作

每个到浏览器IPC连接监视进程句柄。如果句柄被signal(置信号),则渲染进程已经崩溃,tab会显示崩溃信息。现在,我们使用"sad tab"(伤心的页面)来通知用户渲染进程已经崩溃了。网页可以重新载入,也可以用新的浏览开始。发生这些事时候,应注意到,原来的进程没有了,而是创建了新的进程。

render的沙盒处理

给定的webkit是在隔离的进程中运行的。所以我们有机会限制其访问系统资源,比如,我们可以保证render只能通过父浏览器进程访问网络,同样地,我们可以限制其访问宿主操作系统内置的权限访问文件系统。

除此之外,我们也可以设定其访问用户显示器以及相关对象的量,我们让每个渲染进程在隔离的不向用户显示的Windows“桌面”中,这样,就可以阻止一个compromised 渲染器打开一个新的窗口,或者捕获鼠标键盘。

回收内存

在隔离的进程中指定的渲染器,如果作为隐藏了标签页,则以较低的优先级执行,通常情况下,Windows操作系统会将最小化后的进程自动地放入“可用内存”的内存池中,在内存较少的情况下,Windows会将这些内存交换到磁盘中,知道优先级高的时候交换到内存中,这样能提高用户可见程序的的响应率。我们也对隐藏的tab应用相同的原理。当一个渲染进程不在是顶层标签时,我们则释放进程的工作集大小,以提示操作系统可以在必要的时候将这些内存交换到磁盘中。因为我们发现,工作集大小的减少,会导致标签切换时候进程交换的性能,因为,我们是逐渐释放内存的。这就意味着如果用户切换到最近使用过的标签页,标签占用的内存有可能比最近用的页少些,有充足内存的用户,有可能完全不会注意到这个过程:Window仅仅重新声明这些数据,因此在有充足内存时,几乎没有任何性能影响。

 这个过程可以帮助我们在内存较低的情况下保留更多可选用的内存。极少用的标签页所占的内存会完全交换到磁盘中,以便前端的标签页能有足够内存载入。于此相反,单进程的浏览器将所有的页数据都放入到内存中,因此无法清楚地区分哪些数据是可用的,哪些是无用的,浪费内存与CPU性能。

插件


firefox样式的NPAPI插件,运行与自身独立的进程中,与渲染器隔离。细节参见 Plugin Architecture中

参考资料

  • Multi-threaded user interface in Windows on MSDN.
  • 来源: <http://dev.chromium.org/developers/design-documents/multi-process-architecture>

原创粉丝点击