Skip to content

多进程架构

基于 Chromium 现代架构 · 核于 2026-07

速查

  • browser 进程:应用的「chrome」部分——地址栏、书签、前进/后退按钮,外加网络请求、文件访问等特权操作的编排;全浏览器仅一个
  • renderer 进程:tab 内显示网站的一切(解析/渲染/跑 JS);每个 tab(站点隔离下每个 site)一个,被沙箱约束
  • GPU 进程:把各应用的 GPU 请求隔离到单独进程处理(多来源请求要画到同一表面);现代 Chromium 中演进为 Viz
  • plugin 进程:托管网站用到的插件(如当年的 Flash);extension / utility 进程:扩展与音视频解码等杂项
  • Network Service:网络栈从 browser 进程内的线程服务化为独立进程(可按硬件回退为线程)
  • 稳定性:一个 tab 的 renderer 崩溃/卡死只影响该 tab——单进程时代一个页面死循环冻住整个浏览器
  • 安全:OS 按进程限权 → renderer 沙箱化,无任意文件访问;特权操作只能经 IPC 请 browser 代办
  • 内存代价:进程内存不共享,V8 等基础设施每进程一份拷贝
  • 进程数上限:按设备内存与 CPU 能力封顶;超限后同站多 tab 共享一个 renderer 进程
  • Servicification:功能拆成服务——强硬件各自独立进程,弱硬件合并进单进程省内存(与 Android 思路相似)
  • 站点隔离让「每 tab 一进程」细化为「每 site 一进程」,跨站 iframe 独立进程(OOPIF)→ 见站点隔离

一、Chrome 把浏览器拆成了哪些进程

打开 Chrome 任务管理器(菜单 → 更多工具 → 任务管理器),你会看到远不止一个条目。核心成员:

进程数量职责
browser1应用的「chrome」部分:地址栏、书签、前进/后退按钮;并编排网络请求、文件访问等特权能力
renderer多个tab 内显示网站的一切:解析 HTML/CSS、执行 JS、页面渲染
GPU(Viz)1GPU 任务与其他进程隔离处理;因 GPU 要接收多来源请求并画到同一表面而单列
Network Service1(可回退)网络栈:DNS、连接、请求响应(早期是 browser 进程里的 network 线程)
plugin按需托管网站使用的插件(如当年的 Flash)
extension按需扩展程序(本质多是特殊的 renderer)
utility按需音频、数据解码、受保护视频解码等杂项服务

「chrome」一词在这里有双关:小写 chrome 泛指应用中「非网页内容」的界面外框——地址栏、按钮这些;browser 进程管的正是这层外框,加上所有需要特权的幕后工作。

text
        ┌────────────────────────────────────────────┐
        │              browser 进程(总调度)           │
        │   UI(地址栏/书签/按钮) · 特权编排 · 会话历史   │
        └───────┬────────────┬────────────┬──────────┘
             IPC│         IPC│         IPC│
   ┌────────────▼──┐  ┌──────▼────────┐  ┌▼─────────────────┐
   │ renderer ×N   │  │ Viz(GPU)×1   │  │ Network Service ×1│
   │ tab/site 内容  │  │ 合成+上屏      │  │ DNS/连接/请求      │
   └───────────────┘  └───────────────┘  └──────────────────┘

二、单进程 vs 多进程

技术上完全可以把上述一切塞进一个进程的多条线程里——早期浏览器正是这么做的。两种形态的差异:

维度单进程多线程多进程
一个页面崩溃线程崩 → 整个浏览器崩只崩它自己的 renderer,其余 tab 无恙
一个页面卡死可能拖住共享的关键线程 → 全体无响应只有该 tab 无响应,关掉即可
恶意代码越权与浏览器特权代码同一内存空间,一破全破被沙箱进程圈住,还得突破 IPC 这道关
内存共享,省各进程一份拷贝,贵
通信直接读写共享内存,快IPC 消息,慢但边界显式

Chrome 自 2008 年发布起就押注多进程,用内存换稳定与安全。下面把三笔账逐一算清。

三、三笔账:稳定、安全、内存

3.1 稳定性:崩溃被圈在 tab 里

每个 tab 有自己的 renderer 进程。某个页面死循环、内存写坏、渲染引擎触发了 bug——最坏结果是这个 tab 显示崩溃页(「Aw, Snap!」),你关掉它继续用别的 tab。如果所有 tab 跑在一个进程里,任何一个页面出事,所有 tab 一起陪葬。

对前端的直接体感:你写出的死循环只会冻住自己的页面;用户手里其他 tab、地址栏、书签一切照常——那些属于别的进程。

3.2 安全性:沙箱把 renderer 关进笼子

操作系统提供了按进程限制权限的手段,浏览器借此把某些进程沙箱化(sandbox)。renderer 天天执行互联网上任意来路的代码,于是被限得最死——没有任意文件读写权。即使页面里的恶意代码利用漏洞攻破了渲染引擎,它直接能碰到的也只有这个被阉割的进程;想读你的磁盘、发任意请求,必须再突破 IPC 边界骗过 browser 进程/系统服务这道关。

沙箱的实现机制(系统调用过滤、令牌降权等)与配套防线(CORB 等)深挖归浏览器安全叶;本页只需记住:进程是权限的边界

3.3 内存:每个进程都揣着一份拷贝

进程间内存不共享,公共基础设施只能各存一份——最典型的是每个 renderer 里都有一份 V8。同样的功能,多进程形态天然比单进程吃更多内存。

Chrome 的对策是给进程数封顶:上限依设备内存与 CPU 能力而定;达到上限后,新开的同站 tab 不再各自拉起 renderer,而是同一站点的多个 tab 共享一个进程。所以「多进程 = 每 tab 必有独立进程」并不严格成立,弱机器上尤其如此——这也解释了为什么偶尔一个 tab 崩溃会连带同站的另一个 tab。

四、Servicification:按硬件伸缩的架构

三笔账没有静态最优解——强机器不在乎内存、在乎稳定与安全;弱机器反过来。Chrome 的答案是服务化(Servicification):把浏览器程序的每一块功能改写成「服务」,服务与进程解耦:

  • 硬件充裕:每个服务拆成独立进程 → 隔离更彻底,更稳、更安全;
  • 资源受限:多个服务合并进同一个进程 → 少几份拷贝,省内存。

网络栈就是标志性案例:从 browser 进程里的 network 线程,服务化为独立的 Network Service 进程(必要时仍可跑回进程内)。存储、音频等也走了同样的路。Android 系统本身也用类似思路伸缩其服务——移动端正是这套设计最大的受益者。

五、亲手观察:任务管理器读进程

Chrome 任务管理器(菜单 → 更多工具 → 任务管理器;macOS 在「窗口」菜单)是本页内容的实景版,每行一个进程:

text
任务                          内存        CPU   进程 ID
浏览器                        280 MB      1.2   4321   ← browser 进程(仅一个)
GPU 进程                      190 MB      0.8   4335   ← Viz
网络服务                       45 MB      0.1   4340   ← Network Service(服务化的产物)
标签页: news.example          160 MB      0.3   4402   ← renderer
  子框架: https://ads.example  60 MB      0.0   4407   ← OOPIF:跨站 iframe 的独立进程
扩展程序: xxx                  80 MB      0.0   4410   ← 扩展进程

三个观察点:「浏览器」和「GPU 进程」各只有一行(全局唯一);「子框架」行是站点隔离的直接证据;选中某个「标签页」点「结束进程」,只有那个 tab 崩——多进程的稳定性收益眼见为实。更细的归属(每个 frame 在哪个进程、当前隔离模式)看 chrome://process-internals

六、对前端工程师的实际影响

  • 崩溃隔离是 per-process 的:想知道「谁跟谁一起死」,看任务管理器里谁共享进程——同站多 tab 超限共享时会一起崩。
  • 内存账单按进程算:页面里每个跨站 iframe 在站点隔离下都是独立进程(见站点隔离),嵌第三方内容多的页面内存显著更高。
  • 「浏览器很卡」≠「你的页面卡」:你的 JS 只能卡住自己 renderer 的主线程;整个浏览器 UI 卡顿要去怀疑 browser 进程或系统资源。
  • 特权操作必然异步:网络、存储、剪贴板……都要跨进程经 IPC 请服务代办,这是相关 Web API 几乎全是异步的架构原因之一。
  • 别按「进程数 × 均值」估内存:进程数受设备能力、站点隔离策略、超限共享多重因素影响,同一页面在强弱机器上的进程形态可能完全不同(Servicification 的设计初衷)。

顺带一提:Firefox 的多进程改造(Electrolysis/Fission 项目)与 Safari 的 WebContent 进程走的是同一方向——「网页内容进独立沙箱进程」已是现代浏览器的共识形态,Chromium 只是把粒度推得最细。

小结

Chrome 把浏览器拆成 browser(总调度与特权编排)、renderer(每 tab/site 的网页世界)、Viz(合成上屏)、Network Service 与一众 utility 进程。多进程用「每进程一份拷贝」的内存代价,买来两样东西:崩溃被圈在单个 tab、恶意代码被圈在沙箱。进程数按设备能力封顶,超限后同站 tab 共享 renderer;Servicification 更进一步,让服务在强硬件上拆、弱硬件上合。理解「进程 = 崩溃边界 = 权限边界 = 内存账单单位」,后面的站点隔离与导航流程都只是这条原理的展开。下一页深入各进程内的线程