这片文章以高层视角介绍 chromium 的多过程架构。
问题
一个必须意识到的问题:不可能有一个从不解体或者从不卡死的浏览器渲染引擎,也没有一个彻底平安的浏览器渲染引擎。
演变
浏览器从单用户多任务零碎演变成当下的多用户多过程零碎,以前一个 tab 页或者某个插件的 bug 可能会导致整个浏览器不可用。现在同样的状况,互相却不会影响,并且用户数据也是互相隔离限度拜访。
架构概览
- 每个渲染过程独立,每个 tab 可能是一个独立过程(不是相对的,前面会讲)
- 限度每个渲染过程的内存拜访
- 浏览器 主过程 负责整体治理 UI 和每个 Tab 以及插件等,或泛称 浏览器过程
- 每个具体的 tab 过程称之为 渲染过程
渲染过程治理
每一个渲染过程有一个对应的全局 RenderProcess 对象负责维持本人的全局状态以及与浏览器过程(主过程)的通信。同样的在浏览器过程(主过程)那侧有一个与之对应的 RenderProcessHost 对象负责对接 RenderProcess 对象。它们之间通信形式是利用 Chromium 的 IPC 零碎。
视图治理
每一个渲染过程有一个或多个 RenderView 对象,对应各个 Tab 页内容,并有一个对应的浏览器过程(主过程)侧的 RenderViewHost 对象。同一个渲染过程内不同 view 的 id 惟一,但在不同渲染过程之间 view 的 id 是可能反复的。RenderViewHost对象通过 RenderProcessHost 对象来和对应 RenderProcess 对象治理下的对应的 RenderView 对象进行通信。
部件和接口
在渲染过程中
- RenderProcess对象解决与之对应的浏览器过程(主过程)中的 RenderProcessHost 对象 IPC 通信
- RenderView对象通过对应的 RenderProcess 对象、RenderProcessHost对象(以及 Webkit 嵌入层 )来和对应的RenderViewHost 对象通信
在浏览器过程(主过程)中
- 浏览器代表最高层 window 窗口
- RenderProcessHost对象负责对接 RenderProcess 对象,并且通过 IPC 连贯一一对应
- RenderViewHost对象晓得如何分割 RenderView 对象,RenderWidgetHost对象负责输出和绘制 RenderWidget 对象
渲染过程共享
通常状况下每一个 tab 或新开的窗口都是一个独立的 RenderProcess 渲染过程,浏览器过程会创立它并领导其创立一个繁多的 RenderView
然而有时候,不同 tab 或 tab 与窗口之间可能须要共享RenderProcess,比方 window.open 场景。或者过程内存占用率较高时,也会复用。再而,同一个域名下的多个 Tab 或窗口间也会共享渲染过程。共享渲染过程的策略除此之外,还有很多。
解体、异样渲染过程探测
因为存在 RenderProcessHost 和RenderProcessIPC 连贯。当后者产生异样或者解体时就能被监测到,这个时候能够通过重刷或者新起导航,为之创立新的衰弱过程。
渲染过程沙盒化
基于渲染过程的独立性,能够通过沙盒机制限度它的流动,如拜访系统资源,再者限度其只能通过浏览器过程拜访网络、文件系统访问控制等。除此之外,还能够限度其拜访用户出现对象,阻止其关上新的窗口或取得用户键盘输入信息。
内存偿还
暗藏的 tabs 的解决具备低优先级,通常状况下,它们的内存会被偿还到一个可用的内存池。在内存告急情景下,相比高优先级缓存,浏览器会优先将这部分内存替换到硬盘,以此保障用户可见的 tabs 的响应,因为彻底替换后会加大从新唤起 tabs 的提早,所以对暗藏的 tabs 内存替换逐渐进行,进步替换中切回、疾速复原的性能体现。
插件、扩大
插件和扩大运行在独立的过程中,与渲染过程隔离。