背景
我们打开 chrome 浏览器的一个页面,点击 右上角 "选项"菜单 => "更多工具"子菜单,=> 点击 "任务管理器",这就打开了Chrome 的任务管理器的窗口,如下图:
Chrome 任务管理器是用来展示运行中 Chrome 使用的进程信息的。从图中可以看到,Chrome 启动了至少 4 个进程,可是我们仅仅是打开了 1 个页面,为什么要启动这么多进程呢?
带着这个问题,我们开始探索吧!
那进程又是呢?想要了解进程和线程的概念,我们先来了解一下什么是并行处理?
并行处理
计算机中的 并行处理
就是同一时刻处理多个任务。
比如:我们要计算下面三个表达式,并显示出结果:
shell
A = 1 + 2
B = 6 / 2
C = 1 * 3
编码时,我们把这个过程拆分为4个任务:
- 任务1:计算 A = 1 + 2
- 任务2:计算 B = 6 / 2
- 任务3:计算 C = 1 * 3
- 任务4: 显示最后的计算结果
正常情况下,使用 单线程 来处理,也就是分四步按照这个顺序去执行。
如果采用 多线程 的话,就只分两步走,第一步分配三个线程去同时执行三个计算任务,第二步在执行显示任务。
通过对比,我们会发现,单线程需要执行4步,而多线程只需要2步,所以多线程处理(并行处理)能大大提高性能
。
进程与线程
多线程能实现并行处理,即同一时刻能处理多个任务,但线程是不能单独存在的,它是由进程来启动和管理的
。
一个进程就是一个程序的运行实例,即:启动一个程序的时候,操作系统会为该程序创建一块内存,用来存放代码、运行中的数据和一个执行任务的主线程,我们把这样的一个运行环境叫进程
。
单线程与多线程的进程对比图:
可以看得出:线程是依附于进程的,进程中使用多线程能提高运算效率。
同时也得得出一下结论:
1、进程中的任意一线程执行出错,都会导致整个进程的崩溃。
如果我们把上面三个表达式修改一下,让 B中的分母为0:
shell
A = 1 + 2
B = 6 / 0
C = 1 * 3
在线程中,当执行到 B = 6 / 0时,程序就会出错,这样会导致整个进程奔溃,另外两个线程执行的结果也没有了。
2. 线程之间共享进程中的数据。
3. 进程之间的内容相互隔离。
进程隔离是为保护操作系统中进程互不干扰的技术,每一个进程只能访问自己占有的数据,也就避免出现进程 A 写入数据到进程 B 的情况。正是因为进程之间的数据是严格隔离的,所以一个进程如果崩溃了,或者挂起了,是不会影响到其他进程的。如果进程之间需要进行数据的通信,这时候,就需要使用用于进程间通信(IPC)的机制了。
4. 当一个进程关闭之后,操作系统会回收进程所占用的内存。
当一个进程退出时,操作系统会回收该进程所占有的所有资源;即使其中任意线程因为操作不当导致内存泄漏,当进程退出时,这些内存也会被正确回收。
总结:进程与线程之间的关系:
- 进程中的任意一线程执行出错,都会导致整个进程的崩溃。
- 线程之间共享进程中的数据。
- 进程之间的内容相互隔离。
- 当一个进程关闭之后,操作系统会回收进程所占用的内存。
单进程浏览器
单进程浏览器的架构
:指浏览器的所有功能模块都是运行在同一个进程里。这些模块包含了网络、插件、JavaScript 运行环境、渲染引擎和页面等
如此多的功能模块运行在一个进程里,是导致单进程浏览器不稳定、不流畅和不安全的一个主要因素。
不稳定
只要任意一线程意外奔溃就会导致整个浏览器的奔溃。
不流畅
所有页面的渲染模块、JavaScript 执行环境以及插件都是运行在同一个线程中的,这就意味着同一时刻只能有一个模块可以执行。
不安全
插件:通过插件可以获取到操作系统的任意资源,当你在页面运行一个插件时也就意味着这个插件能完全操作你的电脑。如果是个恶意插件,那么它就可以释放病毒、窃取你的账号密码,引发安全性问题。
页面脚本:它可以通过浏览器的漏洞来获取系统权限,这些脚本获取系统权限之后也可以对你的电脑做一些恶意的事情,同样也会引发安全问题。
多进程浏览器
最新的 Chrome 浏览器包括:1 个浏览器(Browser)主进程、1 个 GPU 进程、1 个网络(NetWork)进程、多个渲染进程和多个插件进程。
浏览器进程
:主要负责界面显示、用户交互、子进程管理,同时提供存储等功能。
渲染进程
:核心任务是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页,默认情况下,Chrome 会为每个 Tab 标签创建一个渲染进程。出于安全考虑,渲染进程都是运行在沙箱模式下。
GPU 进程
:GPU 的使用初衷是为了实现 3D CSS 的效果,只是随后网页、Chrome 的 UI 界面都选择采用 GPU 来绘制,这使得 GPU 成为浏览器普遍的需求。最后,Chrome 在其多进程架构上也引入了 GPU 进程。
网络进程
:主要负责页面的网络资源加载。
插件进程
:主要是负责插件的运行,因插件易崩溃,所以需要通过插件进程来隔离,以保证插件进程崩溃不会对浏览器和页面造成影响。
所以,到这里就不难找到开头问题的答案了,仅仅打开了 1 个页面,为什么有 4 个进程?
因为打开 1 个页面至少需要 1 个浏览器进程、1 个网络进程、1 个 GPU 进程以及 1 个渲染进程,共 4 个;如果打开的页面有运行插件的话,还需要再加上 1 个插件进程。
问题记录
✨ 1、如今的多进程架构,为什么偶尔还会碰到一个页面卡死,为什么也导致另一个tab页崩溃呢。
通常情况下是一个页面使用一个进程,但是,有一种特殊情况,叫"同一站点(same-site)",我们将同协议,同根域名的,称为同站点。
比如
shell
https://vuejs.org
https://cn.vuejs.org
https://cn.vuejs.org:8080
这三个都是同站点,同协议:https,同根域名:vuejs.org
Chrome的默认策略是,每个标签对应一个渲染进程。但是如果从一个页面打开了新页面,而新页面和当前页面属于同一站点时,那么新页面会复用父页面的渲染进程。这种情况下,一个页面崩溃了,会导致同一站点的页面同时崩溃,因为他们使用了同一个渲染进程。
✨ 2、浏览器主进程负责将渲染进程生成的图片显示在ui上面,就是说渲染进程输出的最终是图片,浏览器显示的是图片,那么为什么浏览器中鼠标能选中文字?
点击鼠标选中文字的时候,这些消息会传递到渲染进程,渲染进程再合成选中文字的状态,然后更新图片!
总结
- 进程和线程:线程由进程来启动和管理的
- 进程中的任意一线程执行出错,都会导致整个进程的崩溃。
- 线程之间共享进程中的数据。
- 进程之间的内容相互隔离。
- 当一个进程关闭之后,操作系统会回收进程所占用的内存。
- 单线程浏览器架构:不稳定、不流畅、不安全。
- 多线程浏览器架构:浏览器进程、渲染进程、GPU 进程、插件进程。