现代浏览器工做原理(一)——浏览器进程

1、序言

其实作了两年前端,一直都是从代码和网络方面考量问题,一直都没有考虑过跟用户打交道最近的实际上是浏览器。浏览器这个东西怎么说呢,从刀耕火种时代的ie浏览器,到表明现代先进的chrome浏览器,浏览器的整个架构发生了翻天覆地的变化。本章我就来说一下浏览器内核进程和架构的变化。 前端

2、进程、线程的概念

在讲以前,先来看一下会提到的两个概念,进程和线程。咱们知道,ie浏览器实际上是单进程的浏览器。而现代浏览器如谷歌浏览器为例,它是多进程的浏览器。那对比单进程,现代浏览器的多进程有啥优点呢,在讲这个问题以前,咱们先来了解一下进程和线程的概念。chrome

首先进程是一个程序的运行实例,咱们写的代码最后运行其实就是一个进程在运行,因此进程也能够说是程序基本运行的单位。进程也有分主进程、父进程和子进程。主进程是进程的入口,若是你写过Java的话,就会了解到Java里程序执行有一个main方法,这个main方法是程序的入口。通常来讲,若是写的进程够简单的话,主进程就是父进程。父子进程的关系其实就子进程获得的是除了代码段是与父进程共享的意外,其余全部的都是获得父进程的一个副本,子进程的全部资源都继承父进程,获得父进程资源的副本,既然为副本,也就是说,两者并不共享地址空间。,两个是单独的进程,继承了之后两者就没有什么关联了,子进程单独运行。数据库

线程是独立调度和分派的基本单位,也是操做系统可以进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运做单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中能够并发多个线程,每条线程并行执行不一样的任务。在进程中,若是有多个线程处理一个代码块,咱们能够称之为并行处理。好比下面这个代码块在单线程中则是要执行四步,而在多线程中前三行经过三个线程来执行,最后一行代码则在最后的线程中执行展现便可:浏览器

var a = 1 + 1
var b = 2 * 2
var c = 3 / 3
console.log(a, b, c)复制代码

总的来讲,进程和线程之间的关系是这样的:安全

  1. 在进程里任意一个线程出错都会致使整个进程崩溃。
  2. 进程里的线程能够共享进程里的数据。
  3. 当一个进程关闭后,系统会回收进程所占用的资源。
  4. 进程与进程之间的内容相互隔离,若是要实现进程与进程之间的通讯,则用IPC技术。

3、浏览器的单进程时代

在前端处于刀耕火种的年代,微软经过在它的电脑设备上绑定了ie浏览器,逐渐的战胜了昔日强敌网景,独霸整个pc时代。以ie6为例,这款浏览器就是典型的单进程浏览器,并且仍是单线程浏览器。因此你能够想象,这个浏览器是奇慢无比,一个网页挂了就会致使浏览器里全部的页面都挂了。因而乎在后面的ie浏览器,经过多线程技术来试图提高浏览器的速度,但其实单进程不管怎么魔改,都会涉及到这些问题:bash

  1. 不稳定。毕竟只要一个线程挂了就整个浏览器挂了,因此整个浏览器很不稳定。
  2. 不流畅。好比在经过网络获取资源,到渲染流程,若是浏览器上还有插件则还要考虑插件的运行,若是有一个脚本是死循环的,则致使全部页面都要等待这个脚本执行完毕,会致使整个页面十分的不流畅。而且单进程浏览器关闭一个页面也会存在内存泄漏的问题,毕竟不是多进程。多进程关掉一个页面至关于关掉一个进程,系统会自动回收资源。因此这样子会致使浏览器开的越久就越占用内存。
  3. 不安全。上面说到线程是能够共享进程里的资源的,若是一个插件是恶意的,它能够影响到整个浏览器,甚至能够控制你的电脑,来盗取帐号密码。除了插件外,还有一些脚本能够经过钻漏洞来获取权限,引起不少严重的后果。

4、浏览器的多进程时代

既然单进程时代的浏览器是有这么多的漏洞,那么多进程时代的浏览器是怎么样的呢?现代浏览器以chrome浏览器为例,目前的浏览器的多进程架构大体上是这样的:markdown

  1. 浏览器进程。该进程主要是负责界面显示、用户交互、子进程管理,同时提供存储等功能。
  2. 网络进程。该进程主要负责页面的网络资源加载,好比在地址栏输入一个网页地址,网络进程会将请求后获得的资源交给渲染进程处理。
  3. 渲染进程。核心任务是将 HTML、CSS 和 JavaScript 转换为用户能够与之交互的网页,排版引擎 Blink 和 JavaScript 引擎 V8 都是运行在该进程中,默认状况下,Chrome 会为每一个 Tab 标签建立一个渲染进程。出于安全考虑,渲染进程都是运行在沙箱模式下。
  4. GPU进程。其实,Chrome 刚开始发布的时候是没有 GPU 进程的。而 GPU 的使用初衷是为了实现 3D CSS 的效果,只是随后网页、Chrome 的 UI 界面都选择采用 GPU 来绘制,这使得 GPU 成为浏览器广泛的需求。最后,Chrome 在其多进程架构上也引入了 GPU 进程。
  5. 插件进程。主要是负责插件的运行,因插件易崩溃,因此须要经过插件进程来隔离,以保证插件进程崩溃不会对浏览器和页面形成影响。

正是经过多进程,很好的解决了上面所提到的三个问题。首先chrome里新开一个页面至关于新开一个渲染进程,该页面是不会影响到别的页面执行。网络

而后不流畅的问题,因为经过多进程,JavaScript的脚本只有在渲染进程才会被执行,因此若是出现死循环的问题也只是影响当前的页面。而内存泄漏的问题也更容易解决,由于关闭了进程系统就会自动回收资源。多线程

最后就是安全问题。采用多进程架构的额外好处是可使用安全沙箱,你能够把沙箱当作是操做系统给进程上了一把锁,沙箱里面的程序能够运行,可是不能在你的硬盘上写入任何数据,也不能在敏感位置读取任何数据,例如你的文档和桌面。Chrome 把插件进程和渲染进程锁在沙箱里面,这样即便在渲染进程或者插件进程里面执行了恶意程序,恶意程序也没法突破沙箱去获取系统权限。架构

不过笔者也有时偶然发如今chrome中,一个页面的崩溃也会致使全部页面的崩溃。缘由是这样的,一般状况下是一个页面使用一个进程,可是,有一种状况,叫"同一站点(same-site)",具体地讲,咱们将“同一站点”定义为根域名,还包含了该根域名下的全部子域名和不一样的端口。Chrome的默认策略是,每一个标签对应一个渲染进程。可是若是从一个页面打开了新页面,而新页面和当前页面属于同一站点时,那么新页面会复用父页面的渲染进程。官方把这个默认策略叫process-per-site-instance。直白的讲,就是若是几个页面符合同一站点,那么他们将被分配到一个渲染进程里面去。因此,这种状况下,一个页面崩溃了,会致使同一站点的页面同时崩溃,由于他们使用了同一个渲染进程。

为何要让他们跑在一个进程里面呢?由于在一个渲染进程里面,他们就会共享JS的执行环境,也就是说A页面能够直接在B页面中执行脚本。由于是同一家的站点,因此是有这个需求的。

不过多进程浏览器也有它的缺点,第一就是更高的资源占用。浏览器至关于父进程,浏览器下面的进程至关于子进程。由于每一个进程都会包含公共基础结构的副本(如 JavaScript 运行环境),这就意味着浏览器会消耗更多的内存资源。

第二就是更复杂的架构体系。浏览器各模块之间耦合性高、扩展性差等问题,会致使如今的架构已经很难适应新的需求了。

5、面向服务的架构

为了解决这些问题,在 2016 年,Chrome 官方团队使用“面向服务的架构”(Services Oriented Architecture,简称SOA)的思想设计了新的 Chrome 架构。也就是说 Chrome 总体架构会朝向现代操做系统所采用的“面向服务的架构” 方向发展,原来的各类模块会被重构成独立的服务(Service),每一个服务(Service)均可以在独立的进程中运行,访问服务(Service)必须使用定义好的接口,经过 IPC 来通讯,从而构建一个更内聚、松耦合、易于维护和扩展的系统,更好实现 Chrome 简单、稳定、高速、安全的目标。

Chrome 最终要把 UI、数据库、文件、设备、网络等模块重构为基础服务,相似操做系统底层服务。目前 Chrome 正处在老的架构向服务化架构过渡阶段,这将是一个漫长的迭代过程。Chrome 正在逐步构建 Chrome 基础服务(Chrome Foundation Service),若是你认为 Chrome 是“便携式操做系统”,那么 Chrome 基础服务即可以被视为该操做系统的“基础”系统服务层。同时 Chrome 还提供灵活的弹性架构,在强大性能设备上会以多进程的方式运行基础服务,可是若是在资源受限的设备上,Chrome 会将不少服务整合到一个进程中,从而节省内存占用。 

相关文章
相关标签/搜索