一个进程可以向操作系统申请另一个进程去做一些不同的工作。在这种情况下,不同部分的内存就会分配给新的进程。如果两个进程需要交流,他们可以使用IPC(Inter Process Communication)。许多应用被设计为这样:当一个工作进程无响应时,他可以无需停止应用中不同部分的其他进程而重启。
图6:进程间通信
站点独立是一个在Chrome中近期将会出现的功能,它会在每一个跨站的iframe上运行独立的渲染进程。我们已经讨论过每个tab模型会分配一个渲染进程,这允许跨站的iframe运行在一个单独的渲染进程,并在不同的站点之间共享内存空间。在同一个渲染进程下运行a.com和b.com可能看起来okay。同源策略是web的核心安全策略;它保证了一个站点未经准许不能获取到其他站点的数据。绕过这个策略是安全攻击的主要目标。进程独立是最有效的方式去隔离站点。随着Meltdown and Spectre病毒的出现,我们需要利用进程来隔离站点这一点也变得越来越清晰。桌面版Chrome从67版本开始默认开启站点独立,tab中的每一个跨站的iframe都会有一个分离的渲染进程。
图12:站点独立。一个站点中多个渲染进程指向了iframe。
点此看原文 CPU,GPU,内存,和多进程结构 在这个4部分的系列博客中,我们将会从高级体系结构(High-Level Architecture)到渲染管线(Rendering Pipeline)的细节来一探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:计算机的三层结构。硬件机器在下,操作系统在中间,应用在上面。
在进程和线程上执行程序 在深入浏览器的结构之前,另一个要讨论的概念就是进程和线程。一个进程可以描述为一个应用的执行程序。一个线程就是在进程中,执行进程程序部分的东西。 当你打开一个应用,一个进程就创建了。程序可能会创建线程帮助它工作。操作系统给予进程一块内存以便让他工作,而且所有应用相关的状态就存储在那块私有内存空间里面。当你关闭应用,进程就会消失,同时操作系统也会释放那块内存。 图4:进程就像一个有边界的盒子,线程就像抽象的鱼,在进程中畅游。 图5:进程使用内存空间并存储应用数据
一个进程可以向操作系统申请另一个进程去做一些不同的工作。在这种情况下,不同部分的内存就会分配给新的进程。如果两个进程需要交流,他们可以使用IPC(Inter Process Communication)。许多应用被设计为这样:当一个工作进程无响应时,他可以无需停止应用中不同部分的其他进程而重启。 图6:进程间通信
浏览器结构 那么网络浏览器是怎么使用进程和线程的呢?它可能是一个进程包含多个线程或者多个进程和少量线程,以及进程间通过IPC交流。 图7:不同浏览器的进程/线程结构
重要的一点是这些不同的结构实现的细节。这里如何构建一个网络浏览器没有标准的规范。一个浏览器的实现可能和另一个完全不同。
在这一系列的博客文章中,我们将会使用Chrome近期的结构,如下图所示。
在顶层是浏览器进程,和负责应用其他部分的进程相互配合。对于渲染进程来说,会创建多个,并且分配到每一个tab。直到最近,Chrome会尽量给每一个tab一个进程;但现在,它正在尝试给每一个站点一个进程,包括iframes(见站点独立). 图8:Chrome的多进程结构。可以看到图中渲染进程有多层,代表Chrome在每个tab运行了多个渲染进程。
每个进程控制什么?
下面的这个表格描述了每一个Chrome进程,以及它控制什么:
图9:不同的进程负责浏览器界面的不同部分。
这里还有一些其他进程,比如拓展进程和工具进程。如果你想看你的Chrome有多少进程在运行,点击右上角的选项按钮图标,选择更多工具,然后选择任务管理器。这将会打开一个窗口,其中展示了当前正在运行的进程列表和CPU/GPU的使用情况。
Chrome多进程结构的优点
前面,我提到Chrome使用了多渲染进程。在大多数简单的情况下,你可以想象每一个tab都有自己的渲染进程。假如你打开了三个tab,并且每一个tab都是运行独立的渲染进程之下。如果其中的一个tab无响应,那么你可以关闭这个无响应的tab,然后换到其他tab,并且其他tab都是正常的。如果所有的tab都运行在同一个进程下,当其中一个tab无响应时,所有的tab都会无响应,这很不好。 图10:如图所示,多进程tab
另外一个把浏览器的工作分配到多个进程上的好处就是安全和沙箱化。因为操作系统提供了一种方法限制进程的权限,浏览器对于特定的功能,可以沙箱化特定的进程。比如,Chrome 浏览器限制处理任意用户输入的进程(如渲染器进程)对任意文件的访问。
因为进程有它们自己的私有内存空间,他们经常包含了通用基础设施的备份(如Chrome的JavaScript引擎,V8)。这意味着更多的内存占用,因为他们无法像同一进程中的线程那样共享上下文资源。为了节省内存,Chrome对于它能创建的进程数添加了限制。限制的数字取决于你的设备有多少内存和CPU资源,但是当Chrome到达这个限制数时,它开始把同一个网站的多个tab运行在同一个进程下。
节省更多的内存-Chrome中的服务化
同样的实现也被用在了浏览器进程上。Chrome经过结构变化,把浏览器程序的每一个部分作为一个服务以便于可以简单的把他们分到不同的进程中或者整合成一个。
一般来讲,当Chrome运行在强大的硬件上,它可能会把每一个服务拆分到不同的进程中以获得更高的稳定性,但是当它在资源吃紧的设备上,Chrome会将服务聚合到一个进程中以节省内存占用。在内存紧张的情况下,服务聚合这种实现在此之前在一些平台上已经使用,比如Android。 图11:Chrome的服务化(将服务移动到多个进程和一个浏览器进程)
逐帧渲染进程-站点独立
站点独立是一个在Chrome中近期将会出现的功能,它会在每一个跨站的iframe上运行独立的渲染进程。我们已经讨论过每个tab模型会分配一个渲染进程,这允许跨站的iframe运行在一个单独的渲染进程,并在不同的站点之间共享内存空间。在同一个渲染进程下运行a.com和b.com可能看起来okay。同源策略是web的核心安全策略;它保证了一个站点未经准许不能获取到其他站点的数据。绕过这个策略是安全攻击的主要目标。进程独立是最有效的方式去隔离站点。随着Meltdown and Spectre病毒的出现,我们需要利用进程来隔离站点这一点也变得越来越清晰。桌面版Chrome从67版本开始默认开启站点独立,tab中的每一个跨站的iframe都会有一个分离的渲染进程。 图12:站点独立。一个站点中多个渲染进程指向了iframe。
开启站点独立已经是一个多年来的工程尝试。站点独立不像分配不同的渲染进程那样简单;它本质上改变了iframe之间的交流方式。在一个包含iframe的不同进程的页面下,打开开发者工具,意味着开发者工具必须实现后台工作来让它们看起来无缝。甚至在页面中一个简单的Ctrl+F搜索一个关键字,就意味着要搜索不同的渲染进程。你可以看到为什么浏览器工程师会认为站点独立是一个重大的里程碑了。
总结
在这篇文章中,我们了解了浏览器的高层结构以及多进程结构的优点。我们也谈到了Chrome中的服务化和站点独立,这些深深依赖于多进程结构。在下一篇文章中,我们将会深入了解,这些进程和线程为了显示一个网页,会发生什么。