先来说说为什么选择Chromium系浏览器。在众多发行版本的浏览器中,如Chrome、Edge、360浏览或者QQ浏览器等国内的大部分主流浏览器,都是基于Chromium开源软件二次开发而来。而Google基于Chromium开发了Chrome商业浏览器。
Chrome浏览器多进程架构的演变
在了解浏览器从单进程到多进程演变之前,我们先来了解些线程和进程的区别。进程就是程序的运行实例,当程序运行时,系统为该程序创建一块内存,用来存放代码、运行中产生的数据和一个执行主线程,整个内存空间所属的运行环境称为进程。一个进程中可以存在多个线程,线程是依附于进程而存在的。线程与进程的关系有以下特点:
- 线程之间共享父进程中的数据
- 进程中的任意一个线程出错会导致整个进程崩溃
- 进程退出后,操作系统会回收当前进程所开辟的内存
- 进程之间的内容相互隔离,通信需要依靠IPC机制
早期的浏览器使用的是单进程架构,所有的功能模块(包含网络、插件、JavaScript 运行环境、渲染引擎和页面等)都运行在一个进程中。
如此多的模块依靠一个进程完成,就会导致单进程浏览器的不稳定(功能模块或者插件的崩溃会导致浏览器的崩溃,如渲染引擎模块渲染一些复杂的页面)、不流畅(长时间运行的页面代码会阻塞整个线程,导致其他模块没有机会运行,造成视觉上的卡顿)和不安全(插件和功能模块能够直接获取到系统级别的权限)。
多进程架构的浏览器出现,解决了上述单进程浏览器的问题。
从上图中可以看出,早期Chrome浏览器架构中包含一个浏览器注进程、一个网络进程、一个GPU进程、多个渲染进程、多个插件进程。虽然多进程的浏览器解决了上述单进程不稳定、不流畅、不安全的问题,但同时也带来了更高的内存资源占用、更复杂的体系架构。
为了解决这些新问题,Chrome 官方团队使用“面向服务的架构”(Services Oriented Architecture,简称SOA)的思想设计了新的 Chrome 架构。原来的各种模块会被重构成独立的服务(Service),每个服务(Service)都可以在独立的进程中运行,访问服务(Service)必须使用定义好的接口,通过 IPC 来通信,从而构建一个更内聚、松耦合、易于维护和扩展的系统,更好实现 Chrome 简单、稳定、高速、安全的目标。
下面我们来逐个分析下这几个进程的功能。
- 浏览器主进程。主要负责页面显示、用户交互、子进程管理等。
- 渲染进程。核心任务就是将页面的HTML、CSS和Javascript转换成与用户可以交互的页面,排版引擎Blink和Javascript V8引擎都是运行在该进程中。默认情况下,Chrome会为每个Tab标签创建一个渲染进程。由于渲染进程所有的内容都是通过网络获取的,会存在一些恶意代码利用浏览器漏洞对系统进行攻击,所以出于安全考虑,所有的渲染引擎都是运行在沙箱模式下。
- 插件进程。主要负责插件的运行,一个插件一个进程。因为插件的水平参差不齐易崩溃,所以通过插件进程来隔离。
- 网络基础服务进程。主要负责页面的网络资源加载,如下载html、css、image等资源。
- GPU基础服务进程。主要负责实现页面的3D CSS效果等。
- 音频基础服务进程。主要负责音频的播放。
- 其他的基础服务进程等。见文识意即可。
从输入URL地址到页面展示之间过程的分析
未完待续~
相关的一些疑问
如何查看Chrome浏览器的进程任务管理器?
设置 – 更多工具 – 任务管理器。或者通过快捷键 Shift + Esc
。
多进程浏览器是如何解决单进程浏览器的不稳定、不流畅、不安全问题的?
由于进程是相互隔离的,每个页面和插件的崩溃只会影响当前页面和进程,并不会导致整个浏览器的崩溃,所以完美的解决了不稳定因素。由于每个页面是单独的渲染进程,网络资源的下载也由网络进程负责,即使页面是被阻塞了,也只是影响当前页面,所以也解决了不流畅因素。由于渲染进程和插件进程都是在沙箱模式下运行,对敏感的文件位置读写做了限制,即使有恶意程序在运行,也无法突破沙箱去获取系统权限。
为什么还是会出现单个页面卡死导致所有页面崩溃的情况?
Chrome的默认策略是,每个标签页对应一个渲染进程。但是如果从一个页面打开了新页面,而新页面和当前页面属于同一站点(相同协议+相同根域名,https://www.baidu.com和https://pan.baidu.com属于同一站点)时,那么新页面会复用父页面的渲染进程。官方把这个默认策略叫process-per-site-instance。所以,一个页面崩溃了,会导致同一站点的页面同时崩溃,因为他们使用了同一个渲染进程。为什么要让他们跑在一个进程里面呢?因为在一个渲染进程里面,他们就会共享JS的执行环境,也就是说A页面可以直接在B页面中执行脚本。因为是同一家的站点,所以是有这个需求的。