浅述浏览器多进程发展历程

一、浏览器的多进程概括
要想搞明白什么是浏览器的多进程,首先得知道什么是进程。按照维基百科的说法:

进程是计算机中已运行程序的实体。进程是线程的容器,进程本身不运行。程序本身只是指令的集合,进程才是程序(指令)的真正运行。每个程序可以有多个进程,每个进程都有自己的资源。
简单来讲,进程就是CPU资源分配的最小单位,而线程则是CPU调度的最小单位。那什么又是单线程和多线程呢,我们来看一小段代码:

var a = 1 + 10086
var b = 100 * 2
var c = (20 + 1) * 2
var d = 100/10
var e = a + b + c + d
console.log(e)
譬如上面的代码,如果是在单线程的运行环境比如JavaScript,就会需要将上面的计算一个个的去执行完成,然后得出运行结果,也就需要进行六步才能将e打印出来,但如果是在多线程的运行环境中则只需要使用四个线程来同时计算上面的四个运算,待上面的四个运算全部完成后再把他们相加,然后再打印出来。因此使用多线程的并行运算可以大大的提高程序的性能以及效率。
但虽然多线程可以有效的提高程序的运行效率,但它是不能单独存在的,它需要进程的启动与管理。简单来说,进程与线程之间会存在以下四种关系:

进程中的任意一线程执行出错,都会导致整个进程的崩溃。很常见就是JavaScript出现的执行线程出错时会导致整个页面进程的崩溃,而导致页面白屏。
线程之间共享同进程中的数据。
当一个进程关闭之后,操作系统会回收进程所占用的内存。
进程之间的内容会相互隔离。每个进程都只能访问自己访问的数据,这可以有效的避免一个进程的崩溃而影响到其他的进程。如果进程之间有进行数据通信的需要,这时候就需要进程通信(IPC)机制了。

二、浏览器进程发展过程
现在我们都知道浏览器都是多进程的,但其实回顾历史发展的历程,浏览器也经历了一个由单进程到多进程的发展历程。现在就让我们来理一理浏览器单线程到多线程的发展历程。

2.1 青铜时代—单进程的浏览器
2007年之前,所有的浏览器都是单进程的,其中的典型代表就是IE6了。在ID6的时代,页面还是单标签的,一个页面一个窗口,一个窗口一个主线程。因此顾名思义,单进程的浏览器就是指打开一个浏览器,其中包含一个页面,而这个页面的所有的功能模块都运行在同一个进程里,这个模块包括但不限于:网络、渲染引擎、JavaScript运行环境、第三方插件等。具体架构如下图所示:
[图片上传失败…(image-c661e1-1574774887028)]
基于这种情况,单进程的浏览器就存在以下一些问题:

  1. 不稳定
    早期的浏览器都是通过各式各样的插件来实现诸如视频、游戏等功能的,而插件本身又很不靠谱,由于插件运行在浏览器进程之中,因此一个插件的意外崩溃就会导致整个浏览器的奔溃。同样的,渲染引擎也是这个道理,往往一个JavaScript的bu就可能导致整个页面崩溃。

  1. 不流畅
    因为所有页面的JavaScript线程、渲染模块、以及第三方插件都运行在同一个线程之中,因此同一时刻只有一个模块可以执行,这就很有可能出现一个模块发生阻塞的时候而导致其他模块无法运行的情况。此外当时国产的浏览器其实都是基于IE6来进行二次开发的,因此这些国产浏览器虽然基于自身需要,都采用的多标签页的形式,但这些多标签页其实也是跑在同一个线程里的,这就会导致其中一个标签页的卡顿会影响到整个浏览器。

  1. 不安全
    不安全主要是处于两个方面的,一个是插件一个是页面脚本。页面中运行的插件可以读取电脑的资源,执行一些命令。而页面脚本则可以通过浏览器漏洞来获取系统权限,从而应发一系列安全问题

2.2 白银时代—多进程浏览器时代
终于随着 Chrome 浏览器的发布,浏览器架构终于来到了多进程的时代。其中 Chrome 浏览器的进程架构如下:
[图片上传失败…(image-b1bc99-1574774887028)]
其主要作用如下:

Browser进程(浏览器进程):这是浏览器的主进程。有且只有一个,它主要有以下几个作用:
负责浏览器页面的显示与页面交互
负责个页面的管理。创建和销毁其他进程
将 Renderer 进程得到的内存中的 Bitmap ,绘制到用户页面上。
网络资源的管理,下载等。
第三方插件进程:主要负责插件的运行,每种类型的插件都对应着一个进程,只有当使用该插件时才会创建该进程,这样就做到了隔离插件的效果,保证插件的崩溃不会影响到浏览器以及页面。
GPU进程:最多一个,用于3D绘制。这个进程在最初是没有的。但为了实现 3D CSS 的效果,GPU进程成为了浏览器的普遍需求,因此Chrome浏览器也在其多进程的架构上引入了GPU进程。
浏览器渲染进程,也就是浏览器内核,Renderer进程,内部是多线程的:默认每个Tab页面都是一个进程,互相不影响。主要作用是页面渲染,脚本执行,事件处理等。
网络进程:主要负责页面的网络资源的加载,之前是作为一个模块运行在浏览器进程中的,最近几年才独立出来,作为一个单独的进程存在。

然后基于以上的架构,我们来看看他们是如何解决单进程浏览器所存在的问题的:

  1. 解决不稳定
    首先浏览器渲染进程本省就是分离开来的,每个Tab也面都是一个单独的进程,互不影响。其次将第三方插件进程也单独拎了出来,这样就算一个页面的插件出现可问题,也不会影响到这个页面的渲染进程,也就不会对浏览器造成影响了。

  1. 解决不流畅
    在多进程的架构下,JavaScript 只是运行在自己的渲染进程中的,因此即使 JavaScript 代码阻塞了渲染进程,受到影响的也只是当前所渲染的页面。脚本运行也是同样的道理。而对于常常引发性能问题的内存泄漏,在这种架构下,关闭一个页面,会将整个渲染进程给关闭,这时候操作系统就会回收这个进程所占用的内存,也就会不会存在内存泄漏的问题了。

  1. 解决不安全
    采用多金策的架构的一个好处就是可以使用安全沙盒,沙盒通常严格控制其中的程序所能访问的资源,比如,沙盒可以提供用后即回收的磁盘及内存空间。在沙盒中,网络访问、对真实系统的访问、对输入设备的读取通常被禁止或是严格限制。而charome浏览器就将插件进程以及渲染进程所在了沙盒之中,这样即使插件进程以及渲染进程有恶意程序在执行,也无法突破沙盒去获取系统权限,对我们的电脑造成影响。
    虽然现在的多进程的浏览器看起来很美好,解决了原先单进程浏览器所存在的诸多的问题,但同样不可避免的存在着一些问题:

资源占用更多了
更为复杂的体系结构

2.3 黄金时代—SOA架构
为了解决现在浏览器所存在的资源占用高,体系更为复杂的问题,2016年 Chrome 团队就开始使用 “面向服务的架构”(SOA)的思想来设计新的 Chrome 架构。
那什么是SOA呢,简单来说SOA就是一种组件模型,他将应用程序的不同功能单元通过这些服务之间所定义好的接口或者契约联系起来。接口采用中立的方式来进行定义,独立于硬件平台、操作系统以及编程语言。这使得构建各种各样的系统中的服务都可以以一种统一和通用的方式来进行交互。
也就是说, Chrome要做的就是将UI进程、设备、文件、Audio等等模块都编程基础服务,每个服务都可以在独立的进程中运行,而访问这些服务也必须使用定义好的接口,并通过IPC来进行通信。从而构建一个更内聚、松耦合、更易维护和扩展的系统。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章