浏览器:一个 Tab,几个进程?| 带你小小了解一下你吃饭的工具

2,437 阅读13分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情

如果你嫌前面啰嗦,可以直接根据大纲跳转~

前言🍔

本文基于目前世界上使用人数最多的浏览器 —— Chrome,将带你浅浅地了解一下这个你吃饭的工具😛

有一天,我打开了一个标签页,又顺手😗打开了浏览器右上角中选项菜单中任务管理器:

image.png

如果你想我一样装了一堆扩展程序的话,下面还有一大堆扩展程序,开一个网页需要这么任务吗?这个任务是啥?进程还是线程?他们两个有啥差别?为什么不用线程?

你能学到🍕

  • 操作系统中,进程和线程的概念以及他们的关系和区别
  • 单进程和多进程的差别
  • 打开一个页面会创建多少个进程?
  • 浏览器发展的一些历史
  • 浏览器的多进程架构以及好处
  • chrome 服务化架构

image.png

进程?线程?程序?🌭

进程 & 程序

这些个任务,实际上有个专业的名字,名为进程,我们需要对其了简单解一下~

最近这个学期在学操作系统,对这两个概念特别熟悉 ,现在来一起复习一下嘿嘿~

所谓进程就是程序的运行实例。具体点来说,就是我们编写的代码,一开始只是一个存储在硬盘中的静态文件,也就算是程序。接着通过编译就生成了一个二进制可执行文件,之后我们再运行这一个可执行文件。操作系统就会将其装在到内存中,让CPU执行程序的每条指令,并且操作系统会为该程序留出一块内存,用来专门存放程序的代码、以及程序运行用到的数据,还有一个或者多个执行任务的线程以及其他资源 。这样一个运行中的程序、操作系统资源分配与调度的基本单位就叫做进程。

就像我们(学生/员工)就像是CPU,上头(老师/老板)给的任务(静态的指令)就是程序,我们工作的这个动态的就是进程

image.png

线程

前面提到,操作系统会给进程分配线程,也就是线程是依附于进程的~ 其实在早期的操作系统中是没有线程这一个概念的,但是后面计算机科学家们想要有一个 更小的能独立运行的、任务调度执行基本单位,于是就有了线程~

为什么要多线程而不直接用多进程?

多几条道当然比只有一条道方便。但是为什么不直接多进程?

只用单进程的话,我们会被堵塞,那么直接全用多进程的就好了?不,我们仍有麻烦:

  • 进程之间难以通信以及共享数据
  • 维护进程的系统开销很大

所以我们需要一个更下的单位可以有以下功能:

  • 首先要能并发运行
  • 他们之间很多东西靠共享

并发运行: 也就是能同时干活

线程就为此而生

比喻🚘

用一个形象的比喻来说的话就是,线程更像高速公路,变道没有什么难事。但是进程更像火车道,更大更难通信,你需要专门变轨, 这需要一些多的开销

image.png

线程的特点😏

  • 多个线程可以同时存在于进程中
  • 线程可以并发进行
  • 线程之间共享地址空间等资源
  • 当进程中的一个线程崩溃,会导致其所属进程的所有线程全部崩溃

线程 & 进程区别🤔

  • 进程是CPU资源分配的基本单位,线程是CPU任务调度的基本单位
  • 进程独享完整的资源,而线程只能独享必不可少的资源(如线程ID、寄存器等),其他都是共享
  • 不同进程之间的内容是相互隔离的,一个崩溃不会影响其他的
  • 线程能减少并发执行的时间和空间开销

那么这个开销减少主要来自哪里呢? 其实就是靠前面说的共享资源

不论是创建、中止,还是切换,线程所需要操作的资源自然也就少;以及线程之间共享很多东西,那么他们之间交流也就不需要经过 CPU 内核了,效率自然就高了

这里的操作有获取、释放、切换页表

ok,我们现在来开始讲讲浏览器的单线程和多线程

只有一个线程的时代🌯

单进程的浏览器自然只能将所有的程序模块都放在一个进程中

image.png

也就是前面的这些东西,网络相关的、插件相关的、渲染相关的、JavaScript执行相关的,全部放一块了

带来的问题🔊

不流畅🦼

堵塞

等待资源加载时间和大部分情况下的浏览器单线程执行是影响 Web 性能的两大主要原因。

等待时间是需要去克服来让浏览器快速加载资源的主要威胁. 为了实现快速加载,开发者的目标就是尽可能快的发送请求的信息,至少看起来相当快。网络等待时间是在链路上传送二进制到电脑端所消耗的链路传输时间。Web 性能优化需要做的就是尽可能快的使页面加载完成。 ——渲染页面:浏览器的工作原理

大部分情况下,浏览器是单线程执行的。为了有流畅的交互,开发者的目标是确保网站从流畅的页面滚动到点击响应的交互性能。渲染时间是关键要素,确保主线程可以完成所有给它的任务并且仍然一直可以处理用户的交互。通过了解浏览器单线程的本质与最小化主线程的责任可以优化 Web 性能,来确保渲染的流畅和交互响应的及时。

但是如果你就只有一个线程,你想要并发处理的时候,你没得选,你不能确保主线程可以完成所有给它的任务并保持一直可以处理用户的交互。这就会使得浏览器失去响应,卡顿、白屏,带来不好的用户体验~

页面内存泄露

除了单线程导致的堵塞之外,页面内存泄漏也会导致浏览器页面的卡顿现象。

如果某些选项卡会发生内存泄漏,那么随着浏览器运行的时间越来越长、打开过选项卡越来越多,内存泄漏就会越来越多,内存占用也会越来越多,浏览器也可能会变得越来越慢,这是单进程架构的浏览器不流畅的原因

具体如何排查页面内存泄露可以看这一篇文章:检测/排查内存泄漏总结

不稳定🚧

前面提到

  • 当进程中的一个线程崩溃,会导致其所属进程的所有线程全部崩溃

里面的任一模块(插件、GPU图形渲染模块可能比较不稳定)主要出现了问题,那么整个浏览器就会崩溃

不安全🏴‍☠️

不稳定带来的不安全

不稳定自然也就会带来不安全,比如你正在填写某个较长的表单, 突然某个插件导致页面崩溃了,上面填写过的信息也就归零咯。这可能算不上可悲,但绝对算得上可气!

没隔离带来的不安全

在某种程度上,过去的网络浏览器的状态类似于操作系统过去的单用户,协作多任务操作系统。

由于此类操作系统中的行为异常的应用程序可能会破坏整个系统,因此 Web 浏览器中的行为异常的网页也可能因此而崩溃。它只需要一个浏览器或插件错误(或者是恶意插件)即可关闭(坏一点的甚至可能操控?)整个浏览器和所有当前运行的选项卡。

多线程时代🚀

现代操作系统更强大,因为它们将应用程序置于相互隔离的单独进程中。

多线程的浏览器也是类似的道理.

多进程架构🚩

多进程架构是指应用程序使用多个进程的架构,多进程架构可以设计成许多种不同的样子,不过本文只介绍 Chrome 的多进程架构

image.png

图源 Inside look at modern web browser (part 1)

进程作用
Browser Process 浏览器进程控制浏览器的界面,包括地址栏、书签、后退和前进按钮。 还处理网络浏览器中不可见的隐形部分,例如网络请求和文件访问。
Renderer Process 渲染进程控制显示网站的选项卡内的任何内容。比如解析站点的资源然后渲染出选项卡的内容,其内运行着 Blink 和 V8。为了防止恶意代码利用浏览器漏洞来攻击操作系统,该进程被运行在沙箱中
Plugin Process 插件进程控制浏览器的插件每个运行的插件都会创建一个插件进程,对于某些操作系统,插件进程会运行在沙箱中。
GPU Process GPU进程与其他进程隔离处理 GPU 任务,比如绘制浏览器的 UI 界面位图和视图位图。它被分成不同的进程,因为 GPU 处理来自多个应用程序的请求并将它们绘制在同一个表面上。
...可能还有其他的进程,比如扩展进程、代理进程、实用程序进程等等。

多进程特点

其实这几个都是与上面单进程的问题一一对应的,这正是多进程的意义~

更流畅🚲

解决堵塞问题

多进程就可以避免一些单进程无法避免的堵塞问题

内存回收

操作系统可以完全回收给杀死的进程的全部内存,只要用户不是 “从不清理选项卡魔人 ”,浏览器就不会积攒内存泄漏,所以也就能有效避免面内存泄漏导致的浏览器页面的卡顿现象

更稳定

某个进程的崩溃不会影响到其他的进程,每个选项卡都有自己的渲染器进程,一个选项卡无响应,你关闭它不会对其他的选项卡有任何影响。其他选项卡仍能处于活动状态

更安全

为了避免潜在的恶意代码利用浏览器漏洞来攻击操作系统,浏览器将渲染进程和插件进程放了在 沙箱 中运行。沙箱技术,就是操作系统提供了限制进程权限的能力。比如 Chrome 就限制了选项卡读写系统文件的权限。这就是多进程架构的浏览器更安全的原因。

单线程浏览器不能利用沙箱技术吗🤔

线程和沙箱技术看起来没什么关系,实际上,如果线程使用了沙箱技术,该线程对操作系统的权限就会受限,而浏览器肯定是需要一些必要的权限的,所以起码主线程不能运用沙箱技术~ 单线程自然没得选咯

更占用内存?

前面说到,进程之间是相互隔离的,无法像同一个进程中的线程一样共享数据,这样就会使得很多资源无法复用而是不断地拷贝。

一个例子是,每个渲染进程都有一个 Blink 和 V8 的副本。

为什么这个标题要打个问号呢,我们继续往下走~

服务化架构

上面提到的多线程架构的缺点,更占内存Chrome 也在2018 年决定迁移至服务化架构来尽量“解决”该问题。该架构以 service服务 的形式替代原先模块形式来运行浏览器各个进程,以便根据硬件性能(内存大小、CPU能力等)来弹性地控制进程数量。

硬件够强,他就将服务拆分为多个进程来提供更强的稳定性

image.png

图源同上

硬件没那么强时,他就将多个服务整合到一个进程来节省内存

image.png

图源同上
在此更改之前,已在 Android 等平台上使用了类似的整合流程以减少内存使用的方法。

举个例子🌰

一开始网络相关的功能( http、sockets、web sockets等)是由浏览器进程中的网络线程负责,现在重构为了“网络服务”,浏览器根据硬件情况决定在哪里运行网络服务,具体可看 Network Service


值得一提的是,这次架构转型仍在进行中,目前仍在过渡阶段~ 也说明了架构之大之复杂--

学习资源📚

总结 & 收获🥞

回顾了操作系统的基础知识🪐

  • 并发的概念
  • 进程和线程的概念以及区别

话说这里做个统计,校招和社招或者同学在面试中会遇到操作系统的频率高么?

打开一个页面会创建多少个进程?🏝

image.png

实际上是没有固定答案的,反正以我的机器来说

  • 浏览器进程
  • GPU
  • ...
  • 备用渲染
  • 一堆插件

只能说如果硬件受限的话,没装插件也至少四个

  • 浏览器
  • 渲染
  • GPU
  • 网络

浏览器进程相关的历史

  • 单线程浏览器的缺陷
  • 多线程浏览器的特点
  • 复杂的服务化架构~

写作不易~🌝

从学习资源就可以看出写这篇文章我真的看了好多参考文章~

希望你有所收获~

虽然这篇文章可能对你的业务开发没有什么帮助,但往小了说是稍微了解一下浏览器这个吃饭的工具,往大了说正是这些零零散散的知识组合起来,才能构建一个 Web 知识体系,也许才能站在更高的维度来写 Web应用~

又或者说,你知道他们的价值在于 —— 你知道😎

推荐阅读

文中措辞、知识点、格式如有疑问或建议,欢迎评论~你对我很重要~

🌊如果有所帮助,欢迎点赞关注,一起进步⛵这对我很重要~