CPU、GPU、内存以及多进程架构

分享
CPU、GPU、内存以及多进程架构
Photo by Rubaitul Azad / Unsplash

console.info

本文翻译自 Google 的官方文档。该系列共 4 篇文章,主题为从内部观察现代浏览器(Chrome,主要介绍浏览器的内部架构,以及浏览器从输入 URL 到页面呈现的全过程。

原文链接:inside-browser-part1


前言

作为本系列的第一篇,我们先来了解一下计算机的核心术语和 Chrome 的多进程架构模型。

计算机的核心——CPU & GPU

在了解浏览器是如何运行之前,我们必须对它所处的运行环境有所了解,毕竟浏览器是基于这些硬件的。

CPU 中央处理器

4核 CPU 处理任务流程

CPU(Central Processing Unit) 是计算机的大脑。一个 CPU 核心就像一名员工,能够逐个处理分配给它的任务。它可以接收包括数学、艺术在内的各种任务,并将处理结果返回给任务的发布者。

过去,大多数 CPU 都是单核的;而目前,我们经常使用多核 CPU,为计算机提供更加强大的计算能力。

GPU 图像处理单元

大量的 GPU 单元处理任务

GPU(Graphics Processing Unit) 是计算机的另一个重要组成部分。与 CPU 不同,GPU 更擅长处理简单任务,同时一个任务可以由多个 GPU 核心共同处理。

GPU 顾名思义,它的出现就是为了处理图像任务。我们常说的“使用 GPU”“GPU 支持”,就是使用 GPU 实现快速渲染和平滑交互。近些年,随着 GPU 的迅速发展,越来越多的计算任务可以单独运行在 GPU 上。

计算机的三层架构

当你在计算机或手机上打开一个应用时,CPUGPU 会为应用提供计算能力。但是,应用不能直接调用 CPUGPU,必须通过操作系统提供的相关 API 来处理任务。

计算机的三层架构,硬件在底部,应用在顶部,操作系统负责协调硬件和应用

进程(Process)& 线程(Thread)

在深入了解浏览器(Chrome)前,我们还需要了解操作系统提供的两个概念:进程(Process)和线程(Thread)。

进程可以被认为是应用的执行程序,而线程则由进程创建,执行进程所分配的部分任务。

进程是线程的容器

当你打开一个应用程序时,一个进程就会被创建,该进程还可能创建多个线程来帮助它执行程序。

当一个进程被操作系统创建时,操作系统同时会为该进程分配一定大小的内存空间,用来存储进程在执行过程中产生的数据。

不同的进程享有不同区域的内存空间,当进程退出时,进程所占用的内存空间也会得到释放。

应用打开/关闭时,操作系统的行为

一个进程可以向操作系统请求启动另一个进程来帮助它执行任务。由于不同进程占用不同的内存空间,所以各个进程所存储的数据并不共享。如果进程间需要进行数据交互,就只能通过 IPC(Inter Process Communication) 的方式。

许多应用程序被设计成多进程,一个重要原因就是:当某个进程无响应时,只需重新启动该进程,而其他进程不会受到影响。

多进程应用,通过 IPC 通信

浏览器架构

了解进程和线程后,浏览器是如何使用它们来构建架构的呢?总的来说有两种方式:

  1. 使用一个进程及其创建的多个线程,处理网络请求、页面渲染等任务。
  2. 创建多个进程来处理不同任务,并通过 IPC 进行进程间通信。
不同的浏览器架构图

不同的浏览器架构有着不同的实现细节,如何实现一个浏览器也没有固定的标准。因此在这个系列中,我们所描述的浏览器架构是针对 Chrome 浏览器的。

Chrome 采用多进程架构。处在顶端的是浏览器进程(主进程),负责渲染基础部分的 UI,以及协调其他进程处理浏览器中的不同任务。主进程会根据选项卡的情况创建多个渲染进程。Chrome 会为每个选项卡创建一个渲染进程来处理渲染任务,也会尝试为每个站点创建单独的进程,包括 iframe

Chrome 的多进程架构模型

不同进程处理的任务

下表展示了进程名称及其承担的任务:

进程名 任务
Browser(主进程) Chrome 最基础的进程,控制标签栏、地址栏、书签、前进后退按钮,以及网络请求和文件访问等基础功能
Renderer(渲染进程) 控制每一个选项卡的窗口部分
Plugin(插件进程) 控制网站使用的插件,比如 Flash
GPUGPU 进程) 处理由其他进程发出的 GPU 任务;它被分成不同的进程,渲染浏览器窗口中的不同部分
浏览器窗口不同部分被不同的进程处理

上面是浏览器中的主要进程。浏览器还会创建其他进程,比如 Extension(扩展进程)和 Utility(公共进程)等。如果你想查看到底有多少进程正在运行,可以依次点击浏览器右上角的 More Tools(更多工具)和 Task Manager(任务管理器)。弹出的窗口会详细列出每个进程的 ID、名称,以及占用的内存和 CPU 资源。

多进程架构的优点

之前,我们提到过 Chrome 会为每个选项卡开启一个进程,那么这样做的优点是什么呢?

试想一个简单的场景,你在 Chrome 上打开了 3 个页面,当一个页面崩溃了会发生什么?

假设浏览器中的 3 个页面共用一个渲染进程,那么其中一个页面崩溃,就会导致这个渲染进程崩溃,其他两个页面自然也会挂掉。如果这 3 个页面分别由 3 个渲染进程渲染,那么单个页面崩溃并不会影响另外两个页面。

不同选项卡分配不同的渲染进程

浏览器多进程架构的另一个好处在于安全和隐私。由于操作系统可以限制进程的权限,浏览器主进程就能创建只拥有特定权限的进程,使其在沙箱中运行。比如,浏览器创建的渲染进程,其文件访问权限就会受到一定限制。

由于每个进程的内存空间都是私有的,而每个进程都会包含一些公共的基础功能(比如 V8,即浏览器的 JavaScript 解释器),所以进程越多,内存消耗越大。如果不采用多进程架构,而使用“进程—线程”的方式,就能减少内存消耗(线程共享进程占用的内存空间)。因此,Chrome 会根据内存和 CPU 的情况预先确定进程数量的限制。一旦达到限制,Chrome 就会使用“进程—线程”的模式来处理新窗口的创建。

节约内存——Chrome 服务化

同样的节约内存策略也适用于整个浏览器的进程架构。Chrome 在后台运行时,会将不同任务分配给不同进程,或将它们整合进同一个进程。

主要的分配任务的策略如下:

  1. 当硬件资源充足时,Chrome 将不同任务分配给不同进程,以提高运行的稳定性和效率。
  2. 当硬件资源有限时,Chrome 会将一些进程的功能汇集到一个进程中,从而节约内存。
Chrome 针对硬件资源分配任务

单独的渲染进程——站点隔离

站点隔离Chrome 最近推出的一项功能,它确保每个跨站点的 iframe 都在单独的进程中渲染。我们之前讨论过,浏览器会给每个选项卡分配一个进程,那么跨站点的 iframe 也会由同一个进程渲染。这样一来,跨站点的 iframe 就会和主站点处于同一个进程中,共用同一片内存区域。

在同一个进程中同时渲染 a.comb.com 的内容似乎没有太大问题,因为同源策略Web 的核心安全模型,它确保一个站点不能在未经允许的情况下获取另一个站点的数据。但是,随着 Meltdown 和 Spectre 漏洞的出现,我们必须使用进程隔离来确保站点之间相互隔离。在 Chrome 67 版本之后,站点隔离会自动应用在跨站点的 iframe 上。

站点隔离示意图

站点隔离是多年工程积累的成果,远远不是开启一个渲染进程那么简单。它从根本上改变了该 iframe 与其他页面之间的交互方式。比如,打开 DevTools 时,由于 iframe 位于另一个进程,而进程间又相互独立,DevTools 就必须流畅地完成页面内容的获取与合并。即使是简单的查找功能(Ctrl + F),也要通过搜索多个不同的进程来实现。因此,浏览器工程师将该功能的发布视为一个重要的里程碑。

小结

这篇博文大致介绍了以下内容:

  • 浏览器的架构模型。
  • 多进程模型的优点。
  • Chrome 的服务化,目的在于节约内存。
  • 站点隔离的实现方式。

下一篇文章,我们将开始深入研究浏览器为了显示页面,是如何搭配使用这些进程和线程的。

相关文章