浏览器进程架构深度解析
Chrome 多进程架构:Browser/Renderer/GPU 各司其职,为什么一个标签页崩溃不影响其他。
一句话概括
Chrome 采用多进程架构:Browser 进程管 UI/网络/存储,每个标签页跑独立 Renderer 进程,GPU 进程负责合成和绘制。一个标签页崩了不影响其他,利用 IPC(Mojo)跨进程通信,Site Isolation 进一步隔离跨站 iframe。
核心知识点
1. 四大核心进程
| 进程 | 职责 | 每个浏览器有几个 |
|---|---|---|
| Browser | 地址栏/书签/网络请求/文件系统/权限管理 | 1 个 |
| Renderer | 解析 HTML→渲染页面→执行 JS(沙箱隔离) | N 个(每标签页 1 个) |
| GPU | 合成图层、光栅化、调用 OpenGL/Vulkan | 1 个 |
| Utility | 解码音视频/图片、网络服务代理解析 | 若干 |
还有 Plugin 进程(Flash 等,已基本废弃)、Extension 进程(每个扩展独立)、Network Service(Chrome 67+ 独立进程)。
2. 站点隔离(Site Isolation)
Chrome 67 后默认开启。不仅是”每标签页一个进程”,而是同一个标签页内的不同源(origin)的 iframe 也跑独立进程。
1
2
3
4
5
6
标签页渲染 process-a.com
├─ <iframe src="bank.com"> → 独立进程!a.com 的 XSS 拿不到 bank.com 的内存
└─ <iframe src="ads.net"> → 又独立进程!
// 如果你在 a.com 页面发现 XSS,攻击者也只能读写 a.com 的内容
// bank.com 和 ads.net 的 DOM/Cookie/JS 全部在独立进程,物理隔离
这是 Spectre/Meltdown 漏洞后 Chrome 投入巨大的安全加固——CPU 级别的侧信道漏洞无法跨进程读取内存。
3. IPC 通信:进程间怎么”说话”
Renderer 不能直接访问文件系统或网络——所有系统调用都要通过 IPC 发给 Browser 进程(安全沙箱的一部分)。
- 早期:Chrome 用
named pipe(Windows) /Unix domain socket(Linux/macOS) - 现在:Mojo,Chrome 自研的高性能 IPC 框架,支持消息管道、共享内存
postMessage跨 iframe 通信:同源直接传,跨源受targetOrigin限制
1
2
3
4
5
6
// Renderer 进程想要发网络请求:
Renderer: "我要 fetch https://api.example.com/data"
↓ (通过 Mojo IPC)
Browser: "好,我帮你发请求(我有网络权限)"
↓ Mojo 异步回调
Renderer: "收到响应数据,继续渲染"
4. 沙箱机制
Renderer 进程在受限环境运行:
- Windows:使用 Restricted Token + Job Object + 桌面隔离
- macOS:Seatbelt sandbox,限制文件读写/网络/进程创建
- Linux:namespace + seccomp-bpf 过滤系统调用
即使攻击者在 Renderer 进程中执行了任意代码,也无法读写本地文件、窃取其他标签页的 Cookie、或启动新进程。
5. 进程优先级与资源管理
Chrome 不会让所有标签页同等争抢 CPU。前台标签页高优先级,后台标签页受限制:
- 后台标签页
setTimeout最小延迟强制 1000ms(前台 4ms) requestAnimationFrame在后台不触发- 长时间不用的标签页被冻结(frozen),CPU 占用降至 0
- 内存压力大时丢弃(Evict)后台标签页,下次访问重新加载
其实你每天都在用
- Chrome 任务管理器(Shift+Esc):能看到每个进程的 CPU/内存/网络占用,杀手级调试工具
chrome://process-internals:查看每个进程的详细信息和站点隔离状态- 页面崩溃: “哦,这个页面崩溃了”弹窗——崩的是 Renderer 进程,其他标签正常
- Service Worker:也跑在独立进程(或与 Renderer 共享),生命周期不受页面关闭影响
- Electron:复用 Chromium 多进程架构,main 进程 = Browser,renderer 每窗口一个
常见误解(FAQ)
❌ 误区一:”Chrome 每个标签页一定一个进程”
不一定。相同站点(同 eTLD+1)的标签页可能共享 Renderer 进程以节省内存。Site Isolation 保证了不同站的隔离,但 a.example.com 和 b.example.com 可能在同一进程。
❌ 误区二:”Renderer 进程崩了就是页面崩了,重启就好”
Renderer 崩溃时 Browser 进程会清理该进程的所有资源(内存/Cookie/WebSocket),然后展示”崩溃页面”。如果用户点刷新,新建 Renderer 进程重新加载——但之前页面 JS 的状态(变量、闭包)全部丢失。
❌ 误区三:”GPU 进程只拿来渲染 WebGL”
GPU 进程负责所有图层的合成(Compositing),不只是 WebGL。即使普通页面(有 transform/opacity 动画),合成阶段也在 GPU 进程。GPU 进程崩溃 → 所有页面白屏但 JS 仍在运行。
❌ 误区四:”多进程架构是 Chrome 的专利”
Firefox(Project Fission)、Safari、所有 Chromium 系浏览器(Edge/Opera/Brave)都用多进程,区别是进程模型和隔离粒度。Firefox 的 Fission 甚至比 Chrome 更激进——默认给每个跨站 iframe 一个独立进程。
一句话总结
Chrome 的多进程架构是用内存换安全与稳定的经典工程决策——每个标签页独立进程,崩一个不影响全局;沙箱 + IPC 让漏洞即使被利用也无法突破到系统层。