CPU、GPU、内存和多进程架构
在本系列 4 篇博文中,我们将从概要架构到渲染流水线的具体细节,深入探究 Chrome 浏览器的内部。如果您曾经想过浏览器如何将您的代码转换为功能齐全的网站,或者不确定为什么建议使用特定技术来提升性能,那么本系列文章就是为您准备的。
在本系列的第 1 部分中,我们将介绍核心计算术语和 Chrome 的多进程架构。
计算机的核心是 CPU 和 GPU
为了了解浏览器运行的环境,我们需要了解一些计算机部件及其用途。
CPU

首先是中央处理器 (CPU)。CPU 可被视为计算机的大脑。CPU 核心(此处用白领员工表示)可以逐个处理不断到来的许多不同任务。它可以处理从数学到艺术的所有问题,同时还知道如何回复客户来电。过去,大多数 CPU 都是单芯片。核心就像位于同一芯片中的另一个 CPU。在现代硬件中,您通常会获得多个核心,从而为手机和笔记本电脑提供更强大的计算能力。
GPU

图形处理单元(GPU)是计算机的另一个部分。与 CPU 不同,GPU 擅长同时处理多个核心上的简单任务。顾名思义,它最初是用于处理图形的。这就是为什么在图形上下文中,“使用 GPU”或“GPU 支持”与快速渲染和流畅互动相关联。近年来,随着 GPU 加速计算技术的发展,越来越多的计算任务都可以在 GPU 上单独完成。
当您在计算机或手机上启动应用时,CPU 和 GPU 会为应用提供支持。通常,应用使用操作系统提供的机制在 CPU 和 GPU 上运行。

在进程和线程上执行程序

在深入了解浏览器架构之前,我们还需要掌握另一个概念:进程和线程。进程可以描述为应用的正在执行的程序。线程是指位于进程内并执行其进程程序的任何部分的线程。
启动应用时,系统会创建一个进程。该程序可能会创建线程来帮助其执行工作,但这并非必需。操作系统会向进程提供一块内存“slab”供其使用,并且所有应用状态都保留在此私有内存空间中。当您关闭应用时,该进程也会消失,并且操作系统会释放内存。
进程可以请求操作系统启动另一个进程来运行不同的任务。发生这种情况时,系统会为新进程分配内存的不同部分。如果两个进程需要通信,可以使用进程间通信 (IPC) 进行通信。许多应用都是以这种方式设计的,因此如果某个工作器进程无响应,可以重启该进程,而无需停止运行应用不同部分的其他进程。
浏览器架构
那么,Web 浏览器是如何使用进程和线程构建的?它可以是包含许多不同线程的一个进程,也可以是包含少量通过 IPC 通信的线程的许多不同进程。

这里需要注意的重要一点是,这些不同的架构是实现细节。关于如何构建网络浏览器,没有任何标准规范。一款浏览器的方法可能与另一款浏览器完全不同。
在本系列博文中,我们将使用图 8 中所述的 Chrome 最新架构。
顶部是浏览器进程,负责与负责处理应用不同部分的其他进程协调工作。对于渲染程序进程,系统会创建多个进程并将其分配给每个标签页。直到最近,Chrome 才会尽可能为每个标签页分配一个进程;现在,它会尝试为每个网站分配自己的进程,包括 iframe(请参阅网站隔离)。

哪个进程控制哪些内容?
下表介绍了每个 Chrome 进程及其控制的内容:
进程及其控制的内容 | |
---|---|
浏览器 |
控制应用的“Chrome”部分,包括地址栏、书签、返回和前进按钮。 还处理网络浏览器的不可见特权部分,例如网络请求和文件访问。 |
渲染程序 | 控制显示网站的标签页中的所有内容。 |
插件 | 控制网站使用的所有插件,例如 Flash。 |
GPU | 隔离地处理 GPU 任务,不受其他进程的影响。它会分隔到不同的进程中,因为 GPU 会处理来自多个应用的请求,并在同一 Surface 中绘制这些请求。 |

还有更多进程,例如扩展程序进程和实用程序进程。如果您想查看 Chrome 中正在运行的进程数量,请点击右上角的选项菜单图标
,选择“更多工具”,然后选择“任务管理器”。这会打开一个窗口,其中列出了当前正在运行的进程及其使用的 CPU/内存量。Chrome 中多进程架构的好处
我之前提到过,Chrome 使用多个渲染程序。在最简单的情况下,您可以假设每个标签页都有自己的渲染程序进程。假设您打开了 3 个标签页,每个标签页由一个独立的渲染程序运行。
如果某个标签页无响应,您可以关闭该标签页并继续操作,同时让其他标签页保持活跃状态。如果所有标签页都在一个进程中运行,当一个标签页无响应时,所有标签页都会无响应。这很遗憾。

将浏览器的工作分解为多个进程的另一个好处是安全性和沙盒化。由于操作系统提供了限制进程权限的方法,因此浏览器可以将某些进程沙盒化,使其无法使用某些功能。例如,Chrome 浏览器会限制处理任意用户输入的进程(例如渲染程序进程)的任意文件访问权限。
由于进程有自己的私有内存空间,因此它们通常包含常用基础架构的副本(例如 Chrome 的 JavaScript 引擎 V8)。这意味着内存用量会增加,因为它们无法像在同一进程内的线程那样共享。为了节省内存,Chrome 对其可以启动的进程数量施加了限制。此限制因设备的内存和 CPU 功率而异,但当 Chrome 达到此限制时,它会开始在一个进程中运行来自同一网站的多个标签页。
节省更多内存 - Chrome 中的服务化
浏览器进程也采用相同的方法。Chrome 正在进行架构变更,以便将浏览器程序的每个部分都作为服务运行,从而允许分成不同的进程或合并到一个进程。
一般来说,当 Chrome 在强大的硬件上运行时,它可能会将每项服务拆分为不同的进程,以提高稳定性,但如果它在资源受限的设备上运行,Chrome 会将服务合并到一个进程中,以节省内存占用空间。在此变更之前,Android 等平台就已采用类似的方法来合并进程以减少内存用量。
每帧渲染程序进程 - 网站隔离
网站隔离是 Chrome 中最近推出的一项功能,可为每个跨网站 iframe 运行单独的呈现程序进程。我们一直在讨论“每个标签页一个呈现程序”模型,该模型允许跨网站 iframe 在单个呈现程序中运行,并在不同网站之间共享内存空间。在同一渲染器进程中运行 a.com 和 b.com 似乎没什么问题。同源政策是 Web 的核心安全模型;它可确保一个网站在未经同意的情况下无法访问其他网站的数据。绕过此政策是安全攻击的主要目标。进程隔离是分离网站的最有效方式。随着 Meltdown 和 Spectre 的出现,我们更加明确地认识到,需要使用进程来隔离网站。从 Chrome 67 开始,桌面设备上默认启用了网站隔离功能,因此标签页中的每个跨网站 iframe 都会获得单独的呈现进程。

启用网站隔离功能是一项需要多年工程努力才能完成的工作。网站隔离并非仅仅分配不同的渲染程序那么简单;它从根本上改变了 iframe 相互通信的方式。在包含在不同进程中运行的 iframe 的网页上打开开发者工具意味着,开发者工具必须实现后台工作才能使其看起来无缝。即使执行简单的 Ctrl+F 在网页中查找字词,也意味着需要跨不同的渲染程序进行搜索。您可以了解浏览器工程师将网站隔离功能的发布视为一个重大里程碑的原因了!
小结
在本文中,我们简要介绍了浏览器架构,并介绍了多进程架构的好处。我们还介绍了与多进程架构密切相关的 Chrome 中的服务化和网站隔离。在下一篇文章中,我们将开始深入探讨这些进程和线程之间在显示网站时会发生的情况。
您喜欢这篇文章吗?如果您对日后发布的文章有任何疑问或建议,欢迎通过 Twitter 与我联系(我的 Twitter 账号是 @kosamari)。