国内外主流的浏览器,大多采用的是谷歌的Chromium 浏览器内核,Chromium是一个多进程多线程架构的Web引擎,很多应用和底层开发者希望了解Chromium中的进程和线程的种类和用途,以便能利用相关信息提升应用的性能。
为此,本文介绍了Chromium的多进程架构演进历史,并详细列举了Chromium有哪些常见的进程和线程,并详细说明了它们的用途。
希望通过此文能帮助读者初步了解Chromium有哪些常见的进程和线程,并详细说明了它们的用途。
希望通过此文能帮助读者初步了解Chromium/Webview运行时的进程和线程情况。
单进程架构
2007年前,市场上的浏览器基本上都是单进程架构,所有的功能模块都是运行在同一进程中。单一进程的架构有以下几个问题:
1. 稳定性
单进程的浏览器中,任一模块出现问题都会导致整个浏览器的崩溃。特别是早期浏览器的很多功能需要通过插件来实现,而三方实现的插件又特别容易出问题。类似的,过于复杂或者性能低下的JavaScript代码也容易导致JavaScript引擎崩溃,从而导致整个浏览器崩溃。
2. 性能
由于所有的网页都在一个进程中运行,某个网页JavaScript代码运行的很慢或者存在死循环,将会导致整个浏览器卡顿或者失去响应。并且由于渲染引擎可能存在的内存泄露问题,长时间运行的浏览器会占用越来越多的内存。
3. 安全
单进程架构浏览器中所有的组件都运行在一个进程,很难实现合理的安全环境。插件和JavaScript脚本可以利用漏洞获取系统资源权限,导致很多安全性问题。
2008年,Chromium (Chromium是Chrome的开源实现,两者的主要代码是一样的,Chrome相较于Chromium多了一些Google的私有组件。后续无特殊说明,Chromium等同Chrome)发布了如上图的多进程架构。与单进程架构的差别在于独立出了Renderer和Plugin进程。不同的进程间需要通过IPC来通信。Renderer进程即渲染引擎,主要负责页面渲染,包括HTML解析,渲染,JavaScript的执行等工作。
该架构有效的解决了单进程架构的三大问题:
1. 稳定性
各进程是隔离的。单个页面的组件崩溃只影响它所在的Renderer进程,不会导致整个浏览器崩溃,有效的解决了稳定性问题。
2. 性能
浏览器的每个tab都运行在独立的Renderer进程。存在死循环的JavaScript脚本只会影响当前tab,其他页面仍可正常运行。并且渲染引擎的内存泄露也只影响单独的进程,关闭使用内存过多的Renderer即可释放内存,不会影响其他网页的使用。
3. 安全
多进程的架构还引入了Sandbox沙盒机制,Renderer进程和插件进程运行在沙盒中。这些进程无法获取系统资源,资源的获取访问需要通过IPC由Browser进程执行,恶意脚本无法突破沙盒的限制从而影响到系统的安全。
经过多年的发展,Chromium越来越多的功能被分离为独立的进程,例如GPU进程,网络进程。多进程虽然解决了稳定性,性能,安全性问题。但是过多的进程也存在内存占用过多和进程间通信导致的系统架构复杂度上升等问题。为了解决这些问题,Chromium在2016年提出了以SOA(Services Oriented Architecture)为基础的高内聚,低耦合,易扩展的架构。该架构期望将功能组件以服务的形式拆分或聚合,服务可以运行在独立的进程中也可以合并到单一进程。在高端设备上,服务可能会运行在独立的进程以增强稳定性和性能。在低端设备上,多个服务可以合并为单一进程以节省内存的使用。
进程
Chromium的进程模型支持一到多个进程。通常的配置有Browser进程,Renderer进程,GPU进程,网络进程及多个服务进程。在资源较少的设备上可配置为双进程(Browser进程,Renderer进程)或单进程(Browser进程)。需要注意的是,单进程模式的代码没有经过Chromium官方的测试验证,如果要在产品中使用该模式,需要更多的工作维护单进程的稳定性。chrome_string_lookup.cc文件中可以查看到Chromium所有可能的进程和线程名。下图是Windows上打开两个tab时可见的进程:
1.Browser/UI进程
Web引擎的主进程,具有访问系统资源的权限。Windows中显示为浏览器进程,Android上通常就是App的进程。因为主进程中通常也负责和窗口系统的交互,所以有时也被称为UI进程。早期的时候主进程负责UI交互,持久化数据访问,网络资源下载。最新的Chromium中持久化数据访问,网络资源已作为独立的进程存在。
2.Renderer进程
渲染进程,该进程负责页面的渲染和JavaScript脚本的执行。根据配置的不同,能存在多个Renderer进程。简单来说打开的每个网页可能会创建一个renderer进程,但在资源较少的情况下,可以配置域相同的网页共享一个进程,甚至只有一个renderer进程。
Renderer进程是运行在Sandbox中的,该进程没有访问系统资源的权限,所有对资源的访问需求都通过IPC委托给其他功能进程,如网络进程,GPU进程。
3.GPU进程
执行GPU命令的进程,即实际调用opengl es接口的进程。Renderer进程是不能访问GPU的,他对GPU的操作需要通过CommandBuffer委托给GPU进程执行。可以配置不使用独立的GPU进程,这时该进程退化为一个线程运行在主进程中。
4.Network Service进程
执行资源加载的进程,文档资源通过该进程下载并通过Share Memory发送给Renderer进程解析。同样的该进程可配置为主进程中的一个线程。
5.Storage Service进程
为local/session storage, service worker, indexed_db提供存储服务。
6.Data Decoder Service进程
解码进程,执行image,zip等文件的解码。
7.Audio Service进程
音频进程,处理音频文件。
8.Zygote进程
功能和Android的zygote一样,用于加速Renderer进程的创建。
Chromium的架构设计最大化的利用了现代处理的的多核架构,各进程中存在很多线程,每个线程负责特定的任务执行,Chromium常见的线程为以下几类:
1.线程池相关线程,各进程都会存在的线程,进程中可见多个同名的ThreadPool线程。
2.IO相关线程,负责文件的访问,进程间的通信等工作。Browser进程的IO线程为Chrome_IOThread,其他进程的IO线程为Chrome_ChildIOThread。
3.Browser进程中的线程
4.Renderer进程中的线程
5.GPU进程中的线程
Android 系统Webivew是谷歌为Android 提供的 Webivew组件。Android 系统Webivew基于Chromium代码(4.4版本之后),由于嵌入式平台的硬件差异,Android 系统Webivew的进程配置和PC上的Chromium有所不同。
Android 系统Webivew的进程架构遵循Chromium的架构。但是由于平台的限制,在Android L, M, 和N 上,Webivew为单进程模式。在 Android O及之后设备上,Webivew为多进程模式。为了节省内存,多进程模式的Webivew也只有Browser和Renderer进程,GPU和网络服务都以线程的方式运行在Browser进程中,并且renderer进程也只有一个。
Android N 中Webivew可以通过全局配置获取进程模式。也可通过开发者菜单设置使用多进程模式(厂商的开发者菜单中不一定有此选项)。
Android O及之后的版本,Webivew默认为多进程模式,用户无法修改。虽然框架的代码中仍有进程配置相关的代码,但是App无法通过Webivew接口或manifest配置。
国内大厂通常会根据自己的需求基于Chromium引擎开发定制化的Webview,进程配置和Android系统Webview有所不同。开发者可以通过App各子进程中的关键线程名判断该进程属于Chromium的哪个子进程,例如拥有CrRendererMain线程的进程通常是renderer进程。
下面是一些常见应用中的进程,定制化的Webview通常会使用GPU进程以提高性能。
Chromium的进程架构目前已演进到面向服务的多进程架构,随着硬件设备的发展,未来可能会有更多的服务进程,充分的利用硬件资源。对于资源受限的设备,Chromium的进程架构也能方便的进行配置调整以减少资源使用。Web引擎开发者可以根据实际的场景来调整进程配置,应用和底层开发者也可根据实际的进程配置情况来选择应用或者内核的优化策略。
参考文献
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8