浏览器的多进程架构

这片文章以高层视角介绍chromium的多进程架构。

问题

一个必须认识到的问题:不可能有一个从不崩溃或者从不卡死的浏览器渲染引擎,也没有一个彻底安全的浏览器渲染引擎。

演变

浏览器从单用户多任务系统演变成当下的多用户多进程系统,以前一个tab页或者某个插件的bug可能会导致整个浏览器不可用。如今同样的情况,相互却不会影响,并且用户数据也是相互隔离限制访问。

架构概览

image

  • 每个渲染进程独立,每个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或窗口间也会共享渲染进程。共享渲染进程的策略除此之外,还有很多。

崩溃、异常渲染进程探测

因为存在RenderProcessHostRenderProcessIPC连接。当后者发生异常或者崩溃时就能被监测到,这个时候可以通过重刷或者新起导航,为之创建新的健康进程。

渲染进程沙盒化

基于渲染进程的独立性,可以通过沙盒机制限制它的活动,如访问系统资源,再者限制其只能通过浏览器进程访问网络、文件系统访问控制等。除此之外,还可以限制其访问用户呈现对象,阻止其打开新的窗口或获得用户键盘输入信息。

内存归还

隐藏的tabs的处理具有低优先级,通常情况下,它们的内存会被归还到一个可用的内存池。在内存告急情形下,相比高优先级缓存,浏览器会优先将这部分内存交换到硬盘,以此保障用户可见的tabs的响应,因为彻底交换后会加大重新唤起tabs的延迟,所以对隐藏的tabs内存交换逐步进行,提高交换中切回、快速恢复的性能表现。

插件、扩展

插件和扩展运行在独立的进程中,与渲染进程隔离。

你可能感兴趣的:(前端,浏览器)