多进程架构
基于 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 任务管理器(菜单 → 更多工具 → 任务管理器),你会看到远不止一个条目。核心成员:
| 进程 | 数量 | 职责 |
|---|---|---|
| browser | 1 | 应用的「chrome」部分:地址栏、书签、前进/后退按钮;并编排网络请求、文件访问等特权能力 |
| renderer | 多个 | tab 内显示网站的一切:解析 HTML/CSS、执行 JS、页面渲染 |
| GPU(Viz) | 1 | GPU 任务与其他进程隔离处理;因 GPU 要接收多来源请求并画到同一表面而单列 |
| Network Service | 1(可回退) | 网络栈:DNS、连接、请求响应(早期是 browser 进程里的 network 线程) |
| plugin | 按需 | 托管网站使用的插件(如当年的 Flash) |
| extension | 按需 | 扩展程序(本质多是特殊的 renderer) |
| utility | 按需 | 音频、数据解码、受保护视频解码等杂项服务 |
「chrome」一词在这里有双关:小写 chrome 泛指应用中「非网页内容」的界面外框——地址栏、按钮这些;browser 进程管的正是这层外框,加上所有需要特权的幕后工作。
┌────────────────────────────────────────────┐
│ 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 在「窗口」菜单)是本页内容的实景版,每行一个进程:
任务 内存 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 更进一步,让服务在强硬件上拆、弱硬件上合。理解「进程 = 崩溃边界 = 权限边界 = 内存账单单位」,后面的站点隔离与导航流程都只是这条原理的展开。下一页深入各进程内的线程。