构建一个永远不会崩溃或者挂起的排版引擎基本是不可能的,咱们一样也不要期望哪天可以构建出一个绝对安全的排版引擎。php
咱们现阶段的浏览器运行在一个单用户,多合做,多任务的操做系统中。就像一个笨拙的应用程序可让整个系统崩溃同样。一个糟糕的网页一样可让一个现代的浏览器崩溃。其缘由多是一个插件出现bug,最终的结果是整个浏览器以及其余正在运行的标签被销毁。html
现代操做系统已经很是健壮了,它让应用程序在各自的进程中运行和不会影响到其余程序。一个进程崩溃不会损害到其余进程以及操做系统。同时系统会严格的限制一个用户访问另一个用户空间的数据。web
咱们为浏览器的每一个标签(Tab)开辟一个独立的进程,这样咱们防止整个应用程序由于排版引擎的bug而崩溃。一样咱们会严格限制进程访问操做系统及其内存空间。windows
咱们将运行UI和管理标签的插件线程称之为"浏览器进程"或者说是"浏览器",一样,咱们将每一个标签相关的进程称之为"排版进程"或者说是"排版"。咱们使用开源的WebKit做为HTML的解析和排版引擎。浏览器
每一个排版进程都有一个全局的RenderProcess 的对象用以管理和父浏览器进程之间的通信而且保持全局状态。浏览器每个排版进程保持一个对应的RenderProcessHost对象用以管理浏览器状态并负责与其余排版进程进行通信。浏览器进程和排版进程经过Chromium的IPC系统进行通信。安全
每一个排版进程包含一个或多个RenderView 对象。RenderProcess对象负责管理RenderView 对象以及标签(Tabs)的内容。RenderProcessHost里面包含有RenderViewHost。网络
同时每一个RenderViewHost对应着排版进程的一个视图。在一个排版进程里面的视图都有一个不一样的视图ID。这些视图ID有可能和其余排版进程里面的视图ID重名。所以咱们肯定一个位于的视图须要同时借助RenderProcessHost和视图ID。浏览器经过RenderViewHost 对象与指定标签的内容进行通信。RenderViewHost 经过RenderProcessHost 传递消息给RenderView上的RenderProcess 对象。架构
在排版进程内:ide
在浏览器进程内:性能
更多细节能够参考 How Chromium displays web pages
一般状况下。每页新窗口或者是新标签都将在新进程里面打开。浏览器进程负责建立新进程并引导它建立一个RenderView。
有时候有必要让标签或者是窗口共享排版线程。一个网页应用开启了一个新的窗口并采用同步实现进行通信。例如:Javasript里面的window.open。在这种状况下,当咱们建立一个新的窗口或者一个新的标签。咱们须要重用当前进程打开的窗口。咱们还有一种策略:当建立进程的数量太多的时候,咱们会把新建立的标签附加到已有的进程上。或者当用户已经有一个进程打开了所需的地址。这个策略咱们已经在in Process Models. 里面描述过。
每一个浏览器进程的IPC链接会监视进程的句柄(handle),若是句柄指示异常(are signaled),排版引擎已经崩溃并并通知到标签。而后咱们会显示一个"sab tab"页面通知用户排版引擎已经崩溃。这个页面能够经过按刷新键从新加载或者输入一个新的地址进行浏览。当这种状况发生时,咱们通知用户原来的进程已经不存在了咱们须要创新一个新的进程。
排版引擎的沙盒模型
当咱们将WebKit至于一个独立的进程内,就给了咱们机会去限制它访问系统资源。例如,咱们能够确保排版引擎的对网络的访问都是经过它的父进程完成的。一样,咱们能够经过操做系统内置的权限限制排版引擎对文件系统的访问。
除了可以限制排版引擎对文件系统和网络的访问外,咱们还能够增长对其对用户的显示和相关对象的限制。咱们能够在一个用户不可见的windows 桌面上运行一个排版进程。
这样咱们能够防止排版引擎打开新的窗口或者被劫持按键。
给定的排版引擎运做在独立的进程内,它会将隐藏的标签当作低优先级处理。一般状况下,被最小化的窗口的进程会讲他们的内存自动返还到"能够内存"池内,在低内存状况下。窗口会将这部份内存交换到高优先级内存。这样能够保证用户可视的程序获得更多相应。咱们能够讲这个策略用于隐藏的标签。当一个排版进程没有最上层的标签,咱们能够减少这个进程的工做设置大小,这样会提示系统若是有须要能够讲这个进程的内存优先交换出去。由于咱们发现减小工做设置大小会下降两个标签间的切换速度,咱们采起逐步释放的策略。这意味着若是用户在经常使用标签间切换的时候,那些不常被使用的标签其内存会优先被置换出去。
用户若是有足够多的内存运行他们因此的程序的时候他们是不会体会到这个差异的。系统仅仅会回收须要的内存,若是你有足够的内存是不会有性能损失的。
这会帮助咱们在低内存环境下获取更多优化的内存足迹。那些不常使用且被置于后天的标签其内存能够彻底交换给前置的标签。于此造成对比的是,一个单进程浏览器,它全部标签的数据仅仅会随意的散落在内存中,而其不可能将使用过和未使用的内存区分开,既浪费了内存空间有损害了系统性能。
Firefox形式的NPAPI 插件运行在他们本身的进程内,同其余的排版进程保持分离。这些在Plugin Architecture.有进一步的描述。
Multi-threaded user interface in Windows on MSDN.
本文翻译自http://dev.chromium.org/developers/design-documents/multi-process-architecture
转:http://www.cppblog.com/vlient/archive/2008/10/12/63782.html