翻译:疯狂的技术宅 原文链接:https://developers.google.com…
CPU,GPU,内存和多进程架构
在这个由 4 部分组成的系列文章中,我们将介绍 Chrome 浏览器从高级架构到渲染管道的具体细节。如果你想知道浏览器是如何将你的代码转换为功能性网站的,或者你想知道为什么需要使用某些特定技术来提高性能,那么本系列非常适合你。
作为本系列的第 1 部分,我们将介绍核心计算术语和 Chrome 的多进程架构。
注意:如果你熟悉 CPU / GPU 和进程 / 线程的概念,则可以跳到本文的浏览器体系结构部分。
计算机的核心是 CPU 和 GPU
为了理解浏览器运行的环境,我们需要了解一些计算机部件及其功能。
CPU
首先是中央处理单元(Central Processing Unit)—— CPU。CPU 可以被认为是你计算机的大脑。CPU 核心,在这里作为办公室工作人员,可以在他们进来时逐个处理许多不同的任务。它可以处理从数学到艺术的所有事情,同时知道如何回复客户呼叫。在过去,大多数 CPU 都是单芯片。核心就像生活在同一芯片中的另一个 CPU。在现代硬件中,你通常会获得多个核心,从而为你的手机和笔记本电脑提供更强的计算能力。
图 1:4 个 CPU 核心作为办公室工作人员坐在每个办公桌处理任务
GPU
图形处理单元(Graphics Processing Unit)—— GPU 是计算机的另一部分。与 CPU 不同,GPU 擅长处理简单任务,但同时跨多个核心。顾名思义,它最初是为处理图形而开发的。这就是为什么在图形环境中“使用 GPU”或“GPU 支持”与快速渲染和平滑交互相关联。近年来,随着 GPU 加速计算,仅在 GPU 上就可以实现越来越多的计算。
图 2:许多带有扳手的 GPU 核心表明它们可以处理有限的任务
当你在计算机或手机上启动程序时,CPU 和 GPU 用来支持程序的运转。通常,程序使用操作系统提供的相关机制在 CPU 和 GPU 上运行。
图 3:三层计算机体系结构。机器硬件位于底部,操作系统位于中间,应用程序位于顶部。
在进程和线程上执行程序
在深入浏览器架构之前要掌握的另一个概念是 Process 和 Thread。进程可以描述为运行状态中的程序。线程是存在于进程内部并用来执行其程序任务的某一部分。
图 4:过程划定了边界,线程作为在进程内游动的“抽象鱼”
启动程序时,将会创建一个进程。该程序可能会创建线程来帮助它工作,但这是可选的。操作系统为进程提供了一“块”内存,并且所有程序状态都保存在该专用内存空间中。当你关闭程序时,该进程也会消失,操作系统会释放内存。
图 5:进程使用内存空间和存储数据的示意图(sf 不支持 svg 动图上传,看不到请使用技术手段查看原图)
进程可以要求操作系统启动另一个进程来执行不同的任务。当这种情况发生时,将为新进程分配不同的内存。如果两个进程需要通信,他们可以通过使用进程间通信(IPC)来实现。许多程序都是以这种方式工作的,因此如果一个工作进程失去响应,则可以重新启动它,而不会停止运行程序的其他进程。
图 6:通过 IPC 进行通信的独立进程示意图(sf 不支持 svg 动图上传,看不到请使用技术手段查看原图)
浏览器架构
那么如何使用进程和线程构建 Web 浏览器?好吧,它可能是一个具有许多不同线程的进程,或是许多具有少量线程的通过 IPC 进行通信的不同进程。
图 7:不同浏览器体系结构中的进程 / 线程示意图
在这里有非常重要的一点需要注意,这些不同的架构是实现细节。关于如何构建 Web 浏览器并没有标准规范。一种浏览器可能与另一种浏览器的结构完全不同。
在本系列文章中,我们将使用下图中描述的 Chrome 最新架构。
最重要的部分是浏览器进程怎样与程序的其他工作进程进行协调。对于渲染器进程,将创建多个进程并将其分配给每个选项卡。直到不久前,Chrome 才为每个标签提供了一个进程;现在它尝试为每个站点提供自己的进程,其中包括 iframe(请参阅:站点隔离部分)。
图 8:Chrome 的多进程架构图。渲染进程下显示多个图层,表示 Chrome 为每个选项卡运行多个渲染器进程。
每个进程都做些什么?
下表介绍了每个 Chrome 进程及其控制的内容:
进程
做些什么
Browser
控制程序的“chrome”部分,包括地址栏,书签,后退和前进按钮。<br/> 还处理 Web 浏览器的不可见的,和特权部分,例如网络请求和文件访问。
Renderer
负责显示网站的选项卡内的所有内容。
Plugin
控制网站使用的所有插件,例如 flash。
GPU
独立于其他进程的 GPU 处理任务。它被分成多个不同的进程,因为 GPU 处理来自多个程序的请求并将它们绘制在同一个面中。
图 9:指向浏览器 UI 不同部分的不同进程
还有更多的进程,如扩展进程和功能进程。如果你想查看 Chrome 中正在运行的进程数,请点击右上角的选项菜单图标“more_vert”,选择“更多工具”,然后选择“任务管理器”。这将打开一个窗口,其中包含当前正在运行的进程列表以及它们使用的 CPU/ 内存量。
Chrome 中多进程架构的好处
前面我曾提到 Chrome 使用多个渲染器进程。在最简单的情况下,你可以想象每个选项卡都有自己的渲染器进程。假设你打开了 3 个选项卡,每个选项卡都由独立的渲染器进程运行。如果一个选项卡没有响应,就可以关闭无响应的选项卡并继续运行,同时保持其他选项卡处于活动状态。如果所有选项卡都在一个进程上运行,那么当一个选项卡无响应时,所有选项卡都不会响应。那将会很难受。
图 10:显示多进程运行每个选项卡的示意图(sf 不支持 svg 动图上传,看不到请使用技术手段查看原图)
将浏览器的工作分成多个进程的另一个好处是安全性和沙盒。由于操作系统提供了限制进程权限的方法,因此浏览器可以从某些功能中对某些进程进行沙箱处理。例如,Chrome 浏览器限制任意用户输入进程的(如渲染器进程)的任意文件访问。
由于进程有自己的私有内存空间,因此它们通常包含公共基础结构的副本(例如 V8 是 Chrome 的 JavaScript 引擎)。这意味着会消耗更多的内存空间,因为如果它们运行在同一进程内的不同线程上,则无法遵循自己的机制进行共享。为了节省内存,Chrome 限制了它可以启动的进程数量,这种限制因设备的内存和 CPU 功率而异,但当 Chrome 达到限制时,它会在一个进程中运行从同个一站点打开的多个选项卡。
节省更多内存:Chrome 中的服务化
同样的方法适用于浏览器进程。Chrome 正在进行体系结构的变更,以便将浏览器程序的每个部分作为一项服务运行,从而可以轻松拆分为不同的流程或汇总为一个流程。
一般的想法是,当 Chrome 在强大的硬件上运行时,它可能会将每个服务拆分为不同的进程,从而提供更高的稳定性,但如果它位于资源有限的设备上,则 Chrome 会将服务整合到一个进程中,从而节省内存占用。在进行这种更改之前,在 Android 平台上已经使用了类似的方法来整合进程以减少内存使用。
图 11:Chrome 的服务化示意图,将不同的服务转移到多个进程或一个浏览器进程中(sf 不支持 svg 动图上传,看不到请使用技术手段查看原图)
帧渲染器进程:站点隔离
网站隔离是 Chrome 中最近推出的一项功能,可为每个跨网站的 iframe 运行单独的渲染进程。我们一直在讨论每个选项卡一个渲染进程的模型,它允许跨站 iframe 在单个渲染器进程中运行,并在不同站点之间共享内存空间。在同一个渲染进程中运行 a.com 和 b.com 似乎没问题。同源策略是 Web 的核心安全模型,它确保一个站点在未经同意的情况下无法访问其他站点的数据。绕过此策略是安全攻击的主要目标。进程隔离是分离站点的最有效方法。由于 Meltdown 和 Spectre 漏洞,我们更加需要使用进程来隔离站点。默认情况下,自从 Chrome 67 启用桌面隔离功能后,选项卡中的每个跨站点 iframe 都会得到单独的渲染进程。
图 12:站点隔离示意,指向站点内 iframe 的多个渲染器进程
启用站点隔离是一项需要很多年的工作。站点隔离并不像分配不同的渲染进程那么简单;它从根本上改变了 iframe 彼此的交流方式。在运行着不同 iframe 进程的的页面上打开 devtools,意味着 devtools 必须在背后做大量的工作才能使其看起来无缝。即使通过简单的 Ctrl + F 来查找页面中的单词也意味着需要跨越不同的渲染进程进行搜索。这就是浏览器工程师将站点隔离的发布作为一个重要里程碑的原因!
总结
在这篇文章中,我们介绍了浏览器体系结构的高级视图,并介绍了多进程体系结构的优点。我们还介绍了 Chrome 中与多进程架构密切相关的服务化和站点隔离。在下一篇文章中,我们将开始深入研究在显示一个网站时,这些进程和线程之间究竟发生了什么事情。
本文首发微信公众号:jingchengyideng 点击下面链接查看其它章节文章
现代浏览器探秘 (part1):架构
现代浏览器探秘 (part2):导航
现代浏览器探秘 (part3):渲染