Skip to main content

01 Chrome架构

Chrome 打开一个页面需要启动多少进程?点击 Chrome 浏览器右上角的“选项”菜单,选择“更多工具”子菜单,点击“任务管理器”,将打开 Chrome 的任务管理器的窗口:

Chrome 任务管理器用来展示运行中 Chrome 使用的进程信息,只是打开了 1 个页面,却启动了很多个进程。

进程和线程

什么是并行处理

同一时刻处理多个任务

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

程序可以使用单线程来处理,分四步按照顺序分别执行这四个任务:

  • 任务 1 计算 A=1+2;
  • 任务 2 计算 B=20/5;
  • 任务 3 计算 C=7*8;
  • 任务 4 显示最后计算的结果。

采用多线程只需分两步走:

  • 使用三个线程同时执行前三个任务;
  • 再执行第四个显示任务。

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

线程 VS 进程

一个进程是一个程序的运行实例。启动一个程序时,操作系统会为该程序创建一块内存,用来存放代码、运行中的数据和一个执行任务的主线程,这样的一个运行环境叫进程。线程不能单独存在,它是由进程来启动和管理的。

线程是依附于进程的,进程中使用多线程并行处理能提升运算效率。

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

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

当线程执行到 B = 20/0 时,线程会执行出错,会导致整个进程的崩溃,另外两个线程执行的结果也没有了。

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

线程之间可以对进程的公共数据进行读写操作。

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

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

进程之间的内容相互隔离

每一个进程只能访问自己占有的数据,一个进程如果崩溃或者挂起,不会影响到其他进程。进程之间需要进行数据的通信,需要使用用于进程间通信(IPC)的机制。

单进程浏览器

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

不稳定

早期浏览器需要借助于插件来实现诸如 Web 视频、Web 游戏等各种强大的功能,但插件容易出问题,并且还运行在浏览器进程之中,所以一个插件的意外崩溃会引起整个浏览器的崩溃。

渲染引擎模块也是不稳定的,通常一些复杂的 JavaScript 代码有可能引起渲染引擎模块的崩溃,也会导致整个浏览器的崩溃。

不流畅

页面的渲染模块、JavaScript 执行环境以及插件都运行在同一个线程中,同一时刻只能有一个模块可以执行,导致页面卡顿。

运行一个页面再关闭页面,会存在内存不能完全回收的情况,导致使用时间越长,内存占用越高,浏览器会变得越慢。

不安全

插件可以使用 C/C++ 等代码编写,通过插件可以获取到操作系统的任意资源。

页面脚本可以通过浏览器的漏洞来获取系统权限,对电脑做一些恶意的事情。

多进程浏览器早期架构

2008 年 Chrome 发布时的进程架构,页面运行在单独的渲染进程中,页面里的插件也是运行在单独的插件进程之中,进程之间通过 IPC 机制进行通信。

进程相互隔离,当一个页面或者插件崩溃时,影响到的仅仅是当前的页面进程或者插件进程,并不会影响到浏览器和其他页面,解决了页面或者插件的崩溃会导致整个浏览器崩溃,不稳定的问题。

JavaScript 运行在渲染进程中,即使 JavaScript 阻塞了渲染进程,影响到的也只是当前的渲染页面,并不会影响浏览器和其他页面,解决了浏览器不流畅问题。

当关闭一个页面时,整个渲染进程也会被关闭,该进程所占用的内存都会被系统回收,解决了浏览器页面的内存泄漏问题。

采用多进程架构可以使用安全沙箱,沙箱里面的程序可以运行,但是不能在硬盘上写入任何数据,也不能在敏感位置读取任何数据。Chrome 把插件进程和渲染进程锁在沙箱里面,即使在渲染进程或者插件进程里面执行了恶意程序,恶意程序也无法突破沙箱去获取系统权限。

目前多进程架构

  • **浏览器进程。**主要负责界面显示、用户交互、子进程管理,同时提供存储等功能。
  • **渲染进程。**核心任务是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页,排版引擎 Blink 和 JavaScript 引擎 V8 都是运行在该进程中,默认情况下,Chrome 会为每个 Tab 标签创建一个渲染进程。出于安全考虑,渲染进程都是运行在沙箱模式下。
  • **GPU 进程。**开始 GPU 是为了实现 3D CSS 的效果,随后网页、Chrome 的 UI 界面也都选择采用 GPU 来绘制。
  • **网络进程。**主要负责页面的网络资源加载。
  • **插件进程。**主要是负责插件的运行,因插件易崩溃,所以需要通过插件进程来隔离,以保证插件进程崩溃不会对浏览器和页面造成影响。

带来的一些问题:

  • **更高的资源占用。**每个进程都会包含公共基础结构的副本(如 JavaScript 运行环境),浏览器会消耗更多的内存资源。
  • **更复杂的体系架构。**浏览器各模块之间耦合性高、扩展性差等问题,导致现在的架构很难适应新的需求。

未来面向服务的架构

使用面向服务的架构(Services Oriented Architecture,简称 SOA)的思想设计新的架构。

整体架构会朝向现代操作系统所采用的“面向服务的架构” 方向发展,原来的各种模块会被重构成独立的服务(Service),每个服务(Service)都可以在独立的进程中运行,访问服务(Service)必须使用定义好的接口,通过 IPC 来通信,从而构建一个更内聚、松耦合、易于维护和扩展的系统,更好实现 Chrome 简单、稳定、高速、安全的目标。

灵活的弹性架构,在强大性能设备上会以多进程的方式运行基础服务,但是如果在资源受限的设备上,会将很多服务整合到一个进程中,从而节省内存占用。