浏览器内部机制--多进程架构
Last updated
Last updated
近来攻读浏览器机制部分,我会把接下来Chrome浏览器的整体架构到渲染规则进行一个总结,也是我阅读过程的一个积累。
在接下来的(Part1)中我会总结计算机的核心部分和chrome的多进程架构
首先,为了了解浏览器的运行环境,我们先来了解几个计算机的组成部分和他们的作用。
CPU
CPU也就是我们常说的中央处理器。
中央处理器(CPU,Central Processing Unit)是一块超大规模的集成电路,是一台计算机的运算核心和控制核心,它的功能主要是解释计算机指令以及处理计算机软件中的数据,计算机的性能在很大程度上由CPU的性能决定。
如上图所示,当 CPU 知道如何响应人们的需求时,它几乎可以处理各式各样的任务,比如数学,或是艺术。在早些年,CPU 都是由单芯片所构成。每个核就像是在芯片中又存在着另一个 CPU。现代的电子设备基本上都是多核驱动的,这让人们的手机和电脑都具备了更强的计算能力。
GPU
GPU英文全称为Graphic Processing Unit,中文翻译为图形处理器,通常就叫它显卡,GPU是显示卡的大脑,它决定了该显卡的档次和大部分性能。
和 CPU 不同的是,GPU 擅长同时处理跨多核的简单任务。正如它的名字,在设计之初是用来处理图形的。这也正是为什么当图形任务的处理和 GPU 关联起来的时候,通常带来的都是更快速的渲染和更流畅的交互。近年来,随着 GPU 的不断加速和升级,越来越多的计算都可能直接被放在 GPU 上进行了。
当你在手机或电脑上启动一个应用时,CPU 和 GPU 就是为那个应用提供“能量”的两个小兄弟。通常,应用程序通过操作系统提供的“机制”在 CPU 和 GPU 上运行。
再说浏览器架构之前,我们先要来理解一下进程和线程。
先看下定义:
进程是资源(CPU、内存等)分配的基本单位,具有一定功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。
线程是进程的一个实体,是独立运行和独立调度的基本单位(CPU上真正运行的是线程)。线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。
大段的文字,好像不是很好记忆呀~,所以我们下面去试着理解它~
简单的来说,进程的本质: [- 正在执行的一个程序,可以进程比作一个容器或者工厂 -]
通过上图,方便我们了解并记忆:
进程与进程之间相对独立
进程可以包括几个或者上百个线程在运行。
内存(逻辑内存)包括在进程里面,每个进程的内存都是互相独立的,但从一个更高的层次上看,不同的进程也共享着一个巨大的空间,这个空间就是整个计算机。
进程共有文件/网络句柄(handle),这样可以打开同一个文件,抢同一个网络端口。
从不同的视角来看进程:
线程的本质:[- 真正运行的是一个一个的线程 -]
同理,上图我们知道线程包含:
栈(堆栈):主线程的main函数、进行函数调用的参数和返回地址、局部变量等内容都会被压入栈内
PC(Program Couner):程序计数器,PC的指针指向代码所在的内存地址。
TLS(Thread local storage):分配内存,存放变量
总结
进程是什么?它指的是一个运动中的程序。从名字上看,进程表示的就是进展中的程序。一个程序一旦在计算机里运行起来,它就成为一个进程。进程与进程之间可以通信、同步、竞争,并在一定情况下可能形成死锁。
那么线程是什么?我们知道,进程是运转的程序,是为了在CPU上实现多道编程而发明的一个概念。但是进程在一个时间只能干一件事情。如果想同时干两件事,办法就是线程。线程是进程里面的一个执行上下文或者执行序列。
所以浏览器是如何通过进程和线程建立起来的呢?有时会是一个进程和多个不同的线程,或是多个进程和少数线程。
首先要注意一点,不同的浏览器之间的架构可能完全不同,至今没有任何一个规范去限制浏览器做成什么样子。
这里以Chrome为例:
浏览器自身进程:负责与其他进程协作,主要负责浏览器应用的不同部分,如网络、内存等。
渲染进程:浏览器会为每个窗口分配一个渲染进程。在最近的一次更新中,如果够用的话,Chrome 干脆给每个窗口分配了一个进程;
而现在,Chrome 在致力于给每个站点一个独立的进程,包括 iframe。
每个进程都在负责什么?
进程
负责什么
浏览器进程
负责 chrome 的浏览器功能,包括导航栏、书签、后退、前进按钮。当然也负责一些虽然看不到但也很重要的部分,比如网络请求和文件访问
渲染进程
窗口内的网站将如何呈现
插件进程
控制着网站可能用到的所有插件,比如 flash
GPU进程
处理 GPU 任务,与其他进程隔离。它被划分为不同的进程因为 GPU 会处理来自多个应用程序的请求并将其绘制在同一个平面上
之前有提到Chrome是多线程渲染方式。
[- 互不影响 -]。假设你打开了三个浏览器窗口,当其中一个窗口因为某种原因崩掉的时候,你大可以直接关闭这个不再响应的窗口并继续你在其他窗口的工作。我们换一个浏览器,所有的窗口都共享同一个进程,当一个窗口挂掉的时候,所有的窗口都直接挂掉了
[- 安全 -]。由于操作系统提供了一种限制进程“权限”的方法,因此浏览器可以将特定的功能和进程有效的隔离开。比如,Chrome 会限制用来处理用户输入的渲染进程去直接访问文件。
每个进程都有各自的内存空间,因此它们常会各自拥有一份基础功能的拷贝。正因为它们之间不像同一进程中的线程那样能够共享资源,所以就需要更多的内存占用。为了节省内存,Chrome 对其自身可调用的进程在数量上做了限制。具体的限制大小在不同性能的机器上各不相同,唯一确定的是,当达到了这个上限后,Chrome 会将同站点的多个窗口交给同一个进程来管理。
为了节省更多的内存,Chrome 正在进行架构层面的整改,目的是将浏览器的各部分功能变成独立的服务,这样就能轻松的将其拆分为不同的进程,也能更加灵活的互相组合。
主要体现两方面:
1.在性能较高的设备上,它会将每个服务分配至不同的进程,以此来获得更强的运行时稳定性和健壮性
2.在性能设备较低的设备,Chrome 会将服务整合在一个进程中,以此来节省内存的占用。像这种通过整合进程资源以此来节省内存的手段,已经被用于 Android 上了
网站隔离是 Chrome 在其 67 桌面版上新增的特性,基本原则是不同的站点各自运行在自己的沙箱环境中,独享进程,并且不允许通信。
Chrome通常把一个标签默认为一个进程,但是如果网页之间存在共享内容,就会共享同一个进程。而网站隔离可消除共享进程,确保不同网站在不同的进程上。以此防止发生类似Spectre和Meltdown的攻击。由于开启网络隔离功能,需要占据10%的内存,因此Chrome当初并没有默认启用,用户只能通过手动设置启用该功能。但是在Chrome67中,网站隔离功能被默认启用。
Spectre和Meltdown漏洞
Spectre和Meltdown是同一漏洞的不同变体的两个名称。允许恶意程序窃取在受影响机器上处理的敏感数据。
Meltdown漏洞影响几乎所有的Intel CPU和部分ARM CPU,破坏了位于用户和操作系统之间的基本隔离,此攻击允许程序访问内存,因此其他程序以及操作系统的敏感信息会被窃取而Spectre则影响所有的Intel CPU和AMD CPU,以及主流的ARM CPU。破坏了不同应用程序之间的隔离。
这两款漏洞几乎影响到过去20年制造的每一种计算设备,从个人电脑、服务器、云计算机服务器到移动端的智能手机,都受到这两组硬件漏洞的影响。
(感兴趣的同学可以深入研究具体这些漏洞会对浏览器产生哪些影响)
在这篇文章中,我们从宏观的角度了解了浏览器的架构以及这种多进程架构的好处。我们也提到了 Chrome 的服务化以及站点隔离,这些和多进程的架构都有着很深的渊源。
期待下一篇总结😜
参考资料
实际上还会有更多的进程,比如扩展进程和工具进程。如果你想看 Chrome 到底会启动多少个进程,打开右上角的菜单,更多工具,接着选择“任务管理器”。这将会打开一个新的窗口,里面是当前正在运行的进程列表,并且会直观的告诉你目前占用了多少 CPU 和内存(Chrome 吃内存的传言真不是盖的)。
[1]Inside look at modern web browser (part 1):
[2]Mariko Kosaka:
[3]Zhi Hu:
[4]Wei Xin: