正文预热

了解一下基本知识,方便正文理解。

预热一、进程vs线程

微信图片_20190818214158.png

进程 | 能在系统中独立运行,能对系统资源分一杯羹的活动实体,可看成是一个程序的运行实例

【具体介绍】
启动一个程序时,操作系统会为该程序创建一块内存,用来存放它所需要的重要资源,而这个运行环境就叫进程。创建进程时,系统为其分配独立的地址空间(进程能独立运行,互不影响的关键),其中建立数据表维护代码段、堆栈段的和数据段,创建开销非常大。

虽然进程间相互独立,但还是有需要进程间通信的需求,这通过IPC技术实现。

线程 | 进程中的执行单位(即资源调度的基本单位)

【具体介绍】
进程中的“任务执行者”,一个进程有一个或多个线程在执行任务,必然有且至少有一个线程(没执行者该进程创建来有何意义?)。同个进程中的多个线程共享该进程的数据(全局变量、静态变量等),使用相同地址空间(同一个进程下,一个线程挂掉,其他都挂掉的关键原因),创建开销也比进程小得多。

预热二、进程与线程的资源

堆与栈

【具体介绍】
堆是进程和线程共有的,在操作系统对进程初始化的时候分配。运行过程中也可以向系统要额外的堆,但是记得用完了要还给操作系统,要不然就内存泄漏了。
栈是线程独有的,用于保存其自身的运行状态和局部自动变量,在线程开始时初始化,每个线程的栈相互独立。

尽管出现线程因操作不当而内存泄露的情况,但在进程退出后系统仍能将其正确回收

其他

【大致讲讲】
进程中包含用于给其内部线程共享的如进程代码、公有数据等。
线程中包含用于区分其他同一进程中线程的个性属性如线程ID、优先级等。


正文开始

下面来看看浏览器的演化之路到底是怎样走的。

形态一 · 单进程架构

【特征】浏览器所有功能模块都运行在同一个进程中,如下图:
微信图片_20190818230115.png

不稳定 | 易崩,还是整个(浏览器)的崩

【原因】
预热一中已经提到同个进程中的多个线程共享该进程内的所有共享数据,使用相同地址空间,所以只要有一个线程出现问题,整个进程都将崩掉,然而对于单进程浏览器而言,这就是整个浏览器的灾难。在早期浏览器中,一个插件的意外崩溃就会引起整个浏览器的崩溃。

不流畅 | 容易失去响应、出现卡顿

【原因】
上图中可看到“页面线程”的工作压力可大,任务非常多。但是在同一时刻中,线程只能执行一项任务,如果这其中有一个任务执行时间太长,就会影响后续的任务进行,比如写一段JS的死循环,它会独占整个线程,其他任务无法继续进行,这会使浏览器失去响应、变卡顿。

不安全 | 插件权限大,释放病毒、窃取用户资源、无恶不作

【原因】
早期浏览器权限控制松散,外部插件能够轻易获取操作系统的任意资源,也自然安全性差。

形态二 · 早期多进程架构

【特征】在多个进程中执行不同功能模块,如下图:
微信图片_20190819000429.png

减少“不稳定” | 要崩就只崩一个页面

【原因】
预热一中已经提到进程创建时,系统会为其分配独立的地址空间,这使得它们能够相互独立运行,换句话说,也就是运行出错也不会影响到其他进程。当某个页面或插件崩溃时,影响到的仅是当前的页面进程或插件进程,不至于让整个浏览器崩溃。

当几个页面处于同一站点时,共用同一个渲染进程,所以如果几个页面都属同一站点,一个崩了其他也跟着崩。

不流畅 | 个人感觉变化不大

【原因】
多进程的相互独立减少了“不稳定”,而在流畅性上无法左右太多。如果真要说提高了流程性应该是因为进程的分工减轻了单一进程的工作负担,从而让其内部的线程能更快执行任务。

提高“安全性” | 使用安全沙盒,给进程套锁,恶意程序无法突破沙盒去获取更高权限

【原因】
给进程上“锁”,约束权限,让其不能在硬盘中写入恶意数据,也不让其在敏感位置读取数据,自然安全性有所提高。

形态三 · 新时代(当今Chrome)多进程架构

特点:顺应社会需求,进程的分工更加合理,如下图:
微信图片_20190819003627.png

浏览器主进程 | 主要负责界面显示、用户交互、子进程管理,同时提供存储等功能

渲染进程 | 核心任务渲染页面

【具体介绍】
核心便是将HTML、CSS、JavaScript转换为用户可以与之交互的网页。其中排版引擎Blink和JavaScript引擎V8运行在此。默认情况每个Tab标签都有自己的一个渲染进程。

出于安全考虑,渲染进程运行在沙箱模式下

GPU进程 | GPU初衷是实现3D CSS效果,后独立为进程用于界面绘制。

网络进程 | 主要负责页面网络资源加载

插件进程 | 负责插件运行,因插件易崩,通过隔离减少浏览器的“不稳定”。

形态四 · 面向服务的架构SOA

微信图片_20190819004907.png

为何出现该架构 ?

【原因】
多线程模型虽有其好处,但同样不可避免带来了一些问题:
更高的资源占用:每个进程都会包含公共基础结构的副本,意味着浏览器会消耗更多的内存资源;
更复杂的体系结构:浏览器各模块间的耦合性高,扩展性差,导致架构难以适应新需求。

架构亮点

通过将各个模块重构成独立的服务(每个服务在独立的进程中运行),服务间的使用IPC通信,定义好的接口访问,从而构建一个更加内聚、松耦合、易于维护和扩展的系统。


End

参考文章

  1. 重要·线程与进程的区别 链接