Chrom 的多进程架构

多进程架构(原文地址:http://www.chromium.org/developers/design-documents/multi-process-architecture )javascript

这篇文档描述了 Chromium 的上层架构。前端

a、问题所在java

几乎没可能创建一个永远不崩溃或挂机的渲染引擎,也不可能创建一个完美安全的渲染引擎。web

某些方面来讲,如今的 Browser 有点像过去的单用户,多任务的操做系统。在那样的操做系统里,若是有一个胡做非为的程序,将会让整个系统崩溃。也就像一个胡做非为的页面、或插件错误,就能带来整个浏览器和当前运行的全部标签的崩溃。windows

如今的操做系统强壮多了,由于他们将应用程序划分到一个个的独立进程中,这些进程间独立运行,不互相影响,一个程序中的crash通常不会影响到别的应用程序或者整个系统,并且某用户要访问别的用户的数据也是不容许的。浏览器

b、架构概览安全


主进程,也叫作 "Browser" 进程,运行UI 和管理tab网络

一样的,tab进程叫作 "Render" 进程,使用 web-kit 排布引擎来解析和排布 HTML架构

c、管理多个Render 进程性能

每一个Render 进程都有一个全局的 RenderProcess 对象管理和父进程(Browser)间的通讯以及全局的状态,Browser对每一个RenderProcess都维护了一个对应的 RenderProcessHost,用来管理 Browser 的状态和用于通讯。Browser 和 Renderer 之间的通信使用 Chromium's IPC system

d、管理视图

每一个Render 进程都有一个或者多个的RenderView对象,这些对象都由RenderProcess管理,RenderView对应着每一个 Tab的内容。

对应的 RenderProcessHost 维护着一个 RenderViewHost 对象,这个对象对应着每一个 Renderer里的view

每一个 view 拥有一个 viewID,这个viewID是用来区分一个renderer里的多个不一样的view,而且这些id在一个 renderer进程中是惟一的,但在整个Browser 中不是惟一的,因此要区分一个view须要一个RenderProcessHost和一个View ID

Browser到指定的tab内容之间的通讯是经过这些 RenderViewHost 对象来完成的,这些RenderViewHost对象知道怎么把消息经过 RenderProcessHost 传到 RenderProcess ,而后再传到 RenderView

e、组件和接口

在 Render 进程中:

  • RenderProcess 处理 IPC 是经过Browser 中对应的 RenderProcessHost,每一个render 进程都只有一个RenderProcess,这就是browserrender的通讯路径了。

  • RenderView 对象和 Browser 中对应的RenderViewHost通讯(经过 RenderProcess),RenderView 对象也和咱们的WebKit 嵌入层通讯。这个对象表明tab或窗口里的页面内容。

Browser 进程中:

  • Browser对象表明最高层的浏览器窗口。

  • RenderProcessHost对象表明browser 端,browserrenderView的通讯,每一个render 进程只有一个 RenderProcessHost

  • RenderViewHost 对象包装了和 RenderView 的通讯。

  • browser中的RenderWidgetHost 处理RenderWidget的输入和绘画。

f、共享render进程

通常来讲,一个新窗口或者一个新tab,就会建立一个新进程,并建立一个RenderView,但有时候,可能要多个tab共享一个Render进程。

一个web应用打开一个新窗口的时候,他是期待一个同步的通讯的,好比javascript的 window.open,这个状况下,咱们须要在新开的窗口中重用这个进程。

咱们也有办法让一个新的tab指向一个已存在的render进程,这种情形是用于进程太多的状况,或者用户已经有一个进程打开导航到域名。这些办法你能够查看这里(http://www.chromium.org/developers/design-documents/process-models )。

g、监测崩溃和胡做非为的renderer

每一个IPC链接到browser进程, browser进程都会监测进程的句柄。

若是这些句柄激发,render进程已经崩溃而且tabs被告知这个崩溃。到如今为止,咱们会显示一个“sad tab”的页面,通知用户,这个renderer已经崩溃了。点击reload按钮可让这个页面从新装载,或者打开一个新的导航。当这个发生,咱们会通知已经没有进程,并会建立一个新的。

h、让renderer变成一个沙箱

假设Webkit运行在一个单独的进程中,咱们能够限制它访问系统资源。例如咱们可让这个renderer只是经过他的父进程browser访问网络,一样的,咱们能够经过操做系统的权限系统来限制它访问文件系统。

除了限制renderer访问文件系统和网络,咱们还能够限制它访问用户的显示和相关的对象。咱们每一个render进程都运行在一个看不到的窗口里,这个窗口是独立的,叫作“Desktop”,这能够阻止一个“危险的”renderer(被植入危险的代码)打开一个新window或者截取你的键盘点击。

i、把内存还回去

正由于renderer运行在一个单独的进程中,因此咱们须要考虑隐藏的tabs的低优先级问题。

正常的,windows会把一个最小化的进程自动放进一个“有效的内存池”中,当这个进程处于 low-memory 状态,windows 将把这个内存存放到硬盘中,直到他们变为higher-priority的内存。

为了让用户可见的程序更良好的反应,咱们能够把这个原则用于“隐藏”的tabs,当一个renderer不是最高级别的tab时,咱们能够释放那个进程的 “working set”大小,做为对系统的暗示,以便系统能把它的内存转放到硬盘上(若是系统认为须要的话)。

由于咱们发现,减小working set 的大小,也会下降tab切换的性能。当用户在两个tabs之间切换,咱们渐渐的释放内存。这意味着,若是用户切换回最近使用的标签,该标签的内存是更可能被页面化(存到disk)的,而少用的tab反而不会被页面化。

固然,有足够内存的用户不用管这个,由于windows只回收他须要的数据,因此若是内存足够,这样作对性能没有一点的好处。

这有助于咱们在低内存的状况下获得更优化的内存占用,少用的tab将会被彻底从内存替换到硬盘,而前端的tab,将能够整个装载进来内存中。相比之下,一个单进程的浏览器将其全部的tab数据随机的分发到内存中,这样就没办法把使用或者不实用的数据分离得那么清晰,这样就浪费内存以及性能了。

j、插件

Firefox风格的 NPAPI 插件会运行在他本身的进程中,和renderer隔开。具体能够看这里:http://www.chromium.org/developers/design-documents/plugin-architecture 。

相关文章
相关标签/搜索