《Chromium内核原理之blink内核工作解密》
《Chromium内核原理之多进程架构》
《Chromium内核原理之进程间通信(IPC)》
《Chromium内核原理之网络栈》
《Chromium内核原理之网络栈HTTP Cache》
《Chromium内核原理之Preconnect》
《Chromium内核原理之Prerender》
《Chromium内核原理之cronet独立化》
本文主要介绍Chromium的高级架构。
1.背景介绍
2.内核进程架构概述2.1 管理render进程
2.2 管理views3.内核组件和接口
4.共享render进程
5.检测crash或不正常的渲染器
6.沙箱渲染器
7.内存回馈
8.扩展插件
1.背景介绍
构建永不崩溃或挂起的渲染引擎几乎是不可能的。构建一个非常安全的渲染引擎几乎是不可能的。
在某些方面,2006年左右的Web浏览器状态类似于过去的单用户,协作式多任务操作系统。由于在这样的操作系统中行为不端的应用程序可能会占用整个系统,因此Web浏览器中的行为不当网页也可能会崩溃。所需要的只是一个浏览器或插件错误,以关闭整个浏览器和所有当前运行的选项卡。
现代操作系统更加强大,因为它们将应用程序放入彼此隔离的独立进程中。一个应用程序中的崩溃通常不会损害其他应用程序或操作系统的完整性,并且每个用户对其他用户数据的访问受到限制。
2.内核进程架构概述

我们对浏览器选项卡使用单独的进程来保护整个应用程序免受渲染引擎中的错误和故障的影响。我们还限制每个渲染引擎进程对其他进程以及系统其余部分的访问。在某些方面,这为Web浏览带来了内存保护和访问控制带给操作系统的好处。
我们指的是运行UI的主进程,并将选项卡和插件进程作为“浏览器进程”或“浏览器”进行管理。同样,特定于选项卡的进程称为“渲染进程”或“渲染器”。渲染器使用Blink开源布局引擎来解释和布局HTML。
2.1 管理render进程
每个渲染过程都有一个全局RenderProcess对象,该对象管理与父浏览器进程的通信并维护全局状态。浏览器为每个渲染进程维护一个相应的RenderProcessHost,它管理渲染器的浏览器状态和通信。浏览器和渲染器使用Chromium的IPC系统进行通信。
2.2 管理views
每个渲染过程都有一个或多个RenderView对象,由RenderProcess管理,对应于内容选项卡。相应的RenderProcessHost维护与渲染器中每个视图对应的RenderViewHost。每个视图都有一个视图ID,用于区分同一渲染器中的多个视图。这些ID在一个渲染器中是唯一的,但不在浏览器中,因此识别视图需要RenderProcessHost和视图ID。从浏览器到特定内容选项卡的通信是通过这些RenderViewHost对象完成的,这些对象知道如何通过RenderProcessHost将消息发送到RenderProcess和RenderView。
3.内核组件和接口
在render进程中:
- RenderProcess在浏览器中使用相应的RenderProcessHost处理IPC。每个渲染过程只有一个RenderProcess对象。这就是所有浏览器↔渲染器通信的发生方式。
- RenderView对象在浏览器进程(通过RenderProcess)和我们的WebKit嵌入层与其对应的RenderViewHost进行通信。此对象表示选项卡或弹出窗口中一个网页的内容。
在browser进程中:
- Browser对象表示顶级浏览器窗口。
- RenderProcessHost对象表示单个浏览器↔渲染器IPC连接的浏览器端。每个渲染过程在浏览器进程中都有一个RenderProcessHost。
- RenderViewHost对象封装了与远程RenderView的通信,RenderWidgetHost在浏览器中处理RenderWidget的输入和绘制。
4.共享render进程
通常,每个新窗口或选项卡都会在新进程中打开。浏览器将生成一个新进程并指示它创建一个RenderView。
有时需要或希望在标签或窗口之间共享渲染进程。 Web应用程序打开一个期望与其同步通信的新窗口,例如,使用JavaScript中的window.open。在这种情况下,当我们创建一个新窗口或选项卡时,我们需要重用打开窗口的进程。如果进程总数太大,或者用户已经打开导航到该域的进程,我们还有策略为现有进程分配新选项卡。进程模型中描述了这些策略。
5.检测crash或不正常的渲染器
每个与浏览器进程的IPC连接都会监视进程句柄。如果发出这些句柄的信号,则渲染过程已崩溃,并且会向标签通知崩溃。现在,我们显示一个“悲伤标签”屏幕,通知用户渲染器已崩溃。可以通过按重新加载按钮或开始新导航来重新加载页面。发生这种情况时,我们注意到没有进程并创建一个新进程。
6.沙箱渲染器
鉴于渲染器在单独的进程中运行,我们有机会通过沙盒限制其对系统资源的访问。例如,我们可以确保渲染器仅通过其父浏览器进程访问网络。同样,我们可以使用主机操作系统的内置权限限制其对文件系统的访问。
除了限制渲染器对文件系统和网络的访问外,我们还可以限制其对用户显示和相关对象的访问。我们在单独的Windows“桌面”上运行每个渲染过程,这对用户是不可见的。这可以防止受损的渲染器打开新窗口或捕获击键。
7.内存回馈
如果渲染器在单独的进程中运行,则将隐藏选项卡视为较低优先级变得简单明了。通常,Windows上最小化的进程会将其内存自动放入“可用内存”池中。在内存不足的情况下,Windows会在更换优先级较高的内存之前将此内存交换到磁盘,从而有助于保持用户可见程序的响应速度。我们可以将相同的原则应用于隐藏的标签。当渲染过程没有顶级选项卡时,我们可以释放该进程的“工作集”大小作为系统的提示,以便在必要时首先将该内存交换到磁盘。因为我们发现当用户在两个标签之间切换时减小工作集大小也会降低标签切换性能,我们会逐渐释放这个内存。这意味着如果用户切换回最近使用的选项卡,则该选项卡的内存比最近使用的选项卡更容易被分页。拥有足够内存来运行所有程序的用户根本不会注意到这个过程:Windows只会在需要时才会回收这些数据,因此当内存充足时,性能不会受到影响。
这有助于我们在低内存情况下获得更佳的内存占用。与很少使用的背景标签相关联的内存可以完全换出,而前景标签的数据可以完全加载到内存中。相比之下,单进程浏览器将所有选项卡的数据随机分布在其内存中,并且不可能如此干净地分离已使用和未使用的数据,从而浪费内存和性能。
8.扩展插件
Firefox风格的NPAPI插件在自己的进程中运行,与渲染器分开。这在Plugin Architecture中有详细描述。
Site Isolation项目旨在提供渲染器之间的更多隔离,此项目的早期可交付成果包括在隔离的进程中运行Chrome的HTML / JavaScript内容扩展。
参考:
https://www.chromium.org/developers/design-documents/multi-process-architecture
网友评论