01|Chrome架构:仅仅打开了1个页面,为什么有4个进程

270 阅读5分钟

1.并行处理

计算机中的并行处理就是同一时刻处理多个任务,比如我们要计算下面这三个表达式的值, 并显示出结果。

A = 1+2
B = 20/5
C = 7*8

在编写代码的时候,我们可以把这个过程拆分为四个任务:

任务 1 是计算 A=1+2;

任务 2 是计算 B=20/5;

任务 3 是计算 C=7*8;

任务 4 是显示最后计算的结果。

单线程处理:分四步按照顺序分别执行这四个任务。

多线程处理::第一步,使用三个线程同时执行前三个任务;

第二步,再执行第四个显示任务。

对比:使用并行处理能大大提升性能。

二.线程VS进程

进程定义:一个进程就是一个程序的运行实例。详细解释就是,启动一个程序的时候,操作系统会为该 程序创建一块内存,用来存放代码、运行中的数据和一个执行任务的主线程,我们把这样的 一个运行环境叫进程。

进程与线程的关系

1.进程中的任意一线程执行出错,都会导致整个进程的崩溃。

2.线程之间共享进程中的数据

具体表现为:线程之间可以对进程的公共数据进行读写操作

3.当一个进程关闭后,操作系统会回收进程所占用的内存

当一个进程退出时,操作系统会回收该进程所申请的所有资源;即使其中任意线程因为操作 不当导致内存泄漏,当进程退出时,这些内存也会被正确回收。

比如之前的 IE 浏览器,支持很多插件,而这些插件很容易导致内存泄漏,这意味着只要浏 览器开着,内存占用就有可能会越来越多,但是当关闭浏览器进程时,这些内存就都会被系 统回收掉。

4.进程之间的内容相互隔离。

进程隔离是为保护操作系统中进程互不干扰的技术,每一个进程只能访问自己占有的数据, 也就避免出现进程 A 写入数据到进程 B 的情况。正是因为进程之间的数据是严格隔离的,所以一个进程如果崩溃了,或者挂起了,是不会影响到其他进程的。如果进程之间需要进行 数据的通信,这时候,就需要使用用于进程间通信(IPC)的机制了。

单进程浏览器时代

单进程浏览 器是指浏览器的所有功能模块都是运行在同一个进程里,这些模块包含了网络、插件、 JavaScript 运行环境、渲染引擎和页面等。

单进程浏览器不稳定,不流畅,不安全

多进程浏览器时代

对于不稳定问题:由于进程是相互隔离的,所以当一个页面或者插件崩溃 时,影响到的仅仅是当前的页面进程或者插件进程,并不会影响到浏览器和其他页面。

对于不流畅问题:JavaScript 也是运行在渲染进程中 的,所以即使 JavaScript 阻塞了渲染进程,影响到的也只是当前的渲染页面,而并不会影 响浏览器和其他页面,因为其他页面的脚本是运行在它们自己的渲染进程中的。

对于内存泄漏的解决方法那就更简单了,因为当关闭一个页面时,整个渲染进程也会被关 闭,之后该进程所占用的内存都会被系统回收,这样就轻松解决了浏览器页面的内存泄漏问 题。

安全问题:采用多进程架构的额外好处是可以使

用安全沙箱,你可以把沙箱看成是操作系统给进程上了一把锁,沙箱里面的程序可以运行, 但是不能在你的硬盘上写入任何数据,也不能在敏感位置读取任何数据

多进程问题:

1.更高的资源占用:因为每个进程都会包含公共基础结构的副本(如 JavaScript 运行环 境),这就意味着浏览器会消耗更多的内存资源。

2.更复杂的体系架构:浏览器各模块之间耦合性高,扩展性差等问题,会导致现在的架构已经很难适应新的需求了。

问题:即使的如今的多进程架构,偶尔还会碰到一些由于单个页面卡死最终崩溃导致所有页面崩溃的情况,原因?

通常情况下是一个页面使用一个进程,但是,有一种情况,叫"同一站点(same-site)",具体地讲,我们将“同一站点”定义为根域名(例如,geekbang.org)加上协议(例如,https:// 或者http://),还包含了该根域名下的所有子域名和不同的端口,比如下面这三个:

time.geekbang.org www.geekbang.org www.geekbang.org:8080

都是属于同一站点,因为它们的协议都是https,而根域名也都是geekbang.org。你也许了解同源策略,但是同一站点和同源策略还是存在一些不同地方,在这里你需要了解它们不是同一件事就行了。

Chrome的默认策略是,每个标签对应一个渲染进程。但是如果从一个页面打开了新页面,而新页 面和当前页面属于同一站点时,那么新页面会复用父页面的渲染进程。官方把这个默认策略叫process-per-site-instance。

直白的讲,就是如果几个页面符合同一站点,那么他们将被分配到一个渲染进程里面去。 所以,这种情况下,一个页面崩溃了,会导致同一站点的页面同时崩溃,因为他们使用了同一个 渲染进程。

为什么要让他们跑在一个进程里面呢?

因为在一个渲染进程里面,他们就会共享JS的执行环境,也就是说A页面可以直接在B页面中执行 脚本。因为是同一家的站点,所以是有这个需求的。