ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Chrome空白标签页为何有六个进程?拆解Chromium多进程架构

Chrome空白标签页为何有六个进程?拆解Chromium多进程架构 空标签页加六个进程这个组合我几乎每年都要跟人解释一遍。朋友刚打开 Chrome浏览器什么都没干只是停在默认的新标签页上任务管理器里已经躺着好几个 chrome.exeWindows或者一串 Google Chrome HelpermacOS。他第一反应是是不是中毒了第二反应是是不是我装的扩展在偷偷跑。这两个猜测基本都不对——这六个进程是 Chromium 多进程架构在启动时就要支起来的最小班子跟扩展、跟页面内容都没有直接关系。把这六个进程的身份理清楚后面遇到内存怎么这么高某个进程 CPU 跑满了能不能杀为什么关了窗口还有残留这类问题你就有了自己判断的底子而不是靠猜。下面我按启动顺序把它们逐个拆开顺带把常见的验证方法和几个容易踩的坑一起说了。1. 从双击图标到窗口出现启动瞬间发生了什么1.1 空白标签页不等于什么都没加载很多人以为新标签页是空的所以不需要渲染。这个想法错得比较隐蔽。你打开 Chrome 时看到的那个默认页面内部地址是chrome://newtab/它本身也是一份 WebUI 页面由 HTML、CSS、JS 组成同样要走 Blink 渲染引擎去解析、布局、绘制。也就是说哪怕你一个正经网站都没访问Chrome 也必须拉起至少一个渲染进程来画这块空白。再加上地址栏、书签栏、标签条、菜单这些浏览器自身的界面Chrome 从启动的第一毫秒起就是多线程 多进程同时工作的状态。主进程负责窗口和 UI另一个进程负责渲染页面内容还有一个进程专门管 GPU 绘制网络请求、本地存储各自有人管。你看到的什么都没干实际上是十几个组件在按部就班地初始化。这里有个容易忽略的点Chrome 的启动是流水线式的不是等所有进程都就绪才显示窗口。主进程会先把窗口画出来用一块占位区域渲染进程稍后才把内容填进去。所以有时候窗口已经出现但页面还是白的那不是卡了是渲染进程还没把第一帧交上来。1.2 六个这个数字是怎么来的先说明一点这个数字不是一个写死在代码里的常量它是启动阶段的典型观测值会随 Chrome 版本、操作系统、是否登录账号、是否装扩展而变化。我平时在 Windows 上用内置任务管理器看一个干净的新装 Chrome 打开单个新标签页基本稳定在六个左右。为什么是六个而不是两个或二十个原因在于 Chromium 把必须尽早独立的职责拆了出来。主进程不能省GPU 绘制不能省网络栈现在也是独立进程存储服务独立进程页面渲染至少一个进程另外还会预启动一个备用渲染进程用来加速下一次导航。六项凑齐正好是这个最小值。不同版本会有出入。比如某些版本音频服务不是常驻的你放个视频它才出现某些版本会用工具进程Utility来承担存储服务的活。所以如果你数出来是五个或者七个别慌这很正常重点是理解每一类进程在干什么。提示判断进程数量是否异常的正确方式不是去对数字而是去看每个进程在干什么、有没有持续吃 CPU。数字本身就是浮动的。2. 逐个点名初始六个进程的身份与职责这一节是全文最核心的部分。我把这六个进程按谁最重要、谁最容易被误解的顺序讲一遍每讲一个都配一个判断它的方法。2.1 浏览器主进程唯一不能被杀的总指挥任务管理器里显示为Google Chrome不带渲染程序后缀的那个就是主进程。它管的东西多得离谱窗口和标签的生命周期、地址栏输入、书签和历史记录数据库、Cookie 与登录态、下载管理、扩展的调度、以及所有子进程的创建与回收。主进程还有一层不显眼但很关键的职责它是唯一拥有完整系统权限的进程。所有需要访问文件系统、注册表、剪贴板、摄像头的操作子进程都不能自己做必须通过 IPC进程间通信把请求发给主进程由主进程代为执行再把结果传回去。这套设计就是后面要讲的沙箱。判断方法主进程被杀整个浏览器立刻全灭。你不需要真的去杀只要记住这一条就能认出来。另外主进程的图标通常是彩色的浏览器图标而渲染进程在任务管理器里图标的商业软件标识会不一样。2.2 GPU 进程不只是画图那么简单GPU 进程负责硬件加速的合成、光栅化和视频解码。没有它页面滚动和动画会明显发涩视频播放也会更耗 CPU。Chrome 早年间把 GPU 相关工作放在主进程的线程里跑后来独立成进程主要原因是显卡驱动不稳定——驱动崩了会直接把整个浏览器带走独立之后最多是这一帧没画出来Chrome 还能降级到软件渲染继续用。这也是为什么显卡驱动更新后偶尔会出现页面花屏内容过曝或者干脆黑屏。遇到这类现象第一件事不是重装浏览器而是去chrome://gpu看一眼硬件加速是不是被自动禁用了。这个页面会把 GPU 的各项能力、当前启用状态、以及被禁用的原因都列出来信息量非常大。判断方法如果你禁用硬件加速这个进程通常就消失了或者退化成软件合成的角色。在低配机器上关掉硬件加速反而更省电这是很多人都忽略的取舍。2.3 网络服务进程把网络栈关进独立的笼子从 Chrome 75 前后开始网络栈DNS 解析、连接建立、TLS 握手、缓存管理被整体挪到了一个独立的网络服务进程里。这个改动的动机很实在网络栈是解析外部数据的地方是攻击面最大的模块之一。把它单独隔离出来并放进沙箱即使网络栈被攻破攻击者也拿不到文件系统和用户数据。另一个好处是稳定性。网络栈处理的是来自不可信源的数据容易出现内存越界之类的问题。以前这类崩溃会连累整个浏览器现在是这个进程重启一下你顶多看到一次网络连接中断的短暂提示。判断方法在任务管理器里通常显示为网络服务或Utility: Network Service。它启动很早几乎和主进程同时出现。如果你发现所有网页都打不开但浏览器本身正常这个进程就是重点怀疑对象。2.4 渲染进程真正在跑你网页代码的地方渲染进程是 Blink 渲染引擎和 V8 引擎的家。HTML 解析、CSS 计算、布局、绘制、JavaScript 执行全在这里。它也是唯一会被站点隔离策略影响数量的进程——同一个站点的多个标签通常共用一个渲染进程不同站点则分开。渲染进程跑在一个非常严格的沙箱里。这个沙箱到底有多严简单说它默认没有文件系统读写权限、没有注册表访问权限、网络请求也走不了系统原生接口全部得通过 IPC 去找主进程或网络服务代劳。所以你在页面里写 JS 想读本地文件浏览器会直接拦住这不是浏览器管得宽而是架构上就不给这个能力。判断方法任务管理器里名字带渲染程序或Renderer的就是它。你可以打开两个标签页分别访问两个不同网站然后观察进程数量变化能很直观地看出站点隔离的存在。2.5 存储服务进程IndexedDB、缓存和 Service Worker 的仓库存储服务负责 IndexedDB、Cache Storage、Service Worker 相关的持久化数据。它独立成进程的时间比网络服务晚一些大概在 Chrome 80 之后逐步铺开。独立的原因是这些数据同样来自不可信来源一旦解析出错隔离起来能避免拖垮整个浏览器。这个进程平时很低调很多人根本注意不到它。但如果你在做前端开发尤其是调试 Service Worker 或者大量写 IndexedDB 的应用它的异常会直接表现为数据写不进去刷新后缓存没更新这类诡异现象。判断方法通常显示为实用工具存储服务或 Utility: Storage Service。它启动后会一直待着即使你没有打开任何用到本地存储的页面。2.6 预启动的渲染进程为下一次点击提前热身第六个进程是最容易被误解的一个。它是一个已经创建但还没被分配任务的渲染进程专业叫法是 spare renderer。它的存在纯粹是为了性能在站点隔离下每个渲染进程只能服务一个站点那如果每次导航都要现创建一个进程用户就会感觉到明显的延迟。提前预热一个实际导航时直接接管体感上快很多。这个进程平时占用不高但确实会占一份基础内存。低内存设备上Chrome 会根据内存压力决定是否保留它。所以你在内存紧张的机器上可能数不到第六个进程这不是出问题了是系统在自我保护。判断方法在任务管理器的渲染程序列表里它通常没有关联到具体标签页。切换标签的时候可以观察哪个进程的页面字段在变。3. 拆成这么多进程Chrome 到底在图什么理解了六个进程分别是谁之后有必要回答一个更根本的问题为什么不干脆用一个进程全干了单进程浏览器在早期是真实存在的但最终被淘汰原因不是技术做不到而是代价太大。3.1 崩溃隔离一个页面挂掉不该拉着全家陪葬多进程架构最直接的收益就是崩溃隔离。渲染引擎要处理的是互联网上随处可见的畸形 HTML、恶意脚本、超长字符串崩溃概率天然高。单进程模型下任何一个页面崩溃整个浏览器窗口直接消失你正在写的东西、正在看的十几个标签页全部报废。多进程之后崩溃被限制在那个渲染进程内部。你看到的是一张页面崩溃了点击重新加载的提示卡其他标签页照常工作。这个体验差异是实打实的用过早期单进程浏览器的人应该有印象。3.2 沙箱渲染进程被拿掉了哪些权限沙箱不是一句口号它在系统层面有具体实现。以 Windows 为例渲染进程运行在一个受限令牌下并被放进 Job Object 中限制资源使用同时通过完整性级别把它标记为低完整性进程。低完整性进程无法写入大部分系统位置也无法向高完整性进程发送消息。这套机制带来一个直接后果渲染进程想让主进程做任何事都必须走 Mojo IPC。这也是为什么 Chrome 的 IPC 接口设计得极其谨慎每一个接口都要做参数校验因为对面可能已经被攻破了。注意网上流传的很多关闭沙箱提升性能的启动参数代价是把这层防护整个拆掉。除非你在做特定调试否则不要碰。3.3 站点隔离进程边界就是安全边界站点隔离Site Isolation从 Chrome 67 前后在桌面端默认开启。它的规则是不同站点必须落在不同的渲染进程里即使它们被嵌在同一个页面中比如 iframe。这条规则的初衷是防范侧信道攻击——同一进程内的两个页面理论上可以通过共享的 CPU 缓存时序推测对方的数据。站点隔离把安全边界和进程边界画到了一起代价是进程数量增加、内存占用上升。这也是为什么开几个网页内存就上去了最主要的答案不是哪个页面特别臃肿而是每个跨站页面都在单开一间房。3.4 多进程的代价内存账单与 IPC 开销多进程不是白拿的。每个进程都有自己的 V8 堆、Blink 对象图、线程栈和进程本身的内核结构基础开销通常在几十 MB 量级。开二十个跨站标签页这部分底噪叠加起来就相当可观了。IPC 也是成本。页面里一次简单的本地存储读取在多进程模型下是一次跨进程调用涉及序列化和上下文切换。Chrome 团队为此做了大量优化把高频调用改成共享内存传递但架构本身的代价无法完全消除。所以准确的说法是Chrome 用内存换稳定和安全。这个取舍在今天的硬件条件下是划算的但要理解它才不至于一边享受着隔离带来的稳定一边抱怨内存占用高。4. 自己动手验证三个工具把进程看穿光看描述容易忘动手数一遍印象最深。这一节给三个可以直接用的观测手段从最简单到最深入。4.1 内置任务管理器为什么它比系统任务管理器好用Chrome 自带一个任务管理器Windows 上按Shift Esc直接呼出macOS 在菜单里找窗口 任务管理器。它比系统任务管理器的优势在于语义清晰它会告诉你每个进程对应哪个标签页、哪个扩展、哪个子框架还会单列 CPU、内存、网络三个维度的实时占用。系统任务管理器只能看到一堆同名进程完全分不清谁是谁。这也是很多人误杀渲染进程的原因——杀错了标签页直接白屏杀错了主进程整个浏览器退出。一个实用技巧把内存列点一下排序找出占用最高的那个看它的页面字段是什么。如果是一个你根本不认识的第三方页面那就是某个标签页在偷偷吃内存如果显示的是扩展名那就是扩展的问题。4.2 几个信息密度极高的内部页面Chrome 有一批chrome://开头的内部页面调试时非常有用列几个我常用的地址能看什么chrome://version完整版本号、命令行参数、可执行文件路径、配置文件路径chrome://gpu硬件加速状态、显卡驱动信息、被禁用的功能及原因chrome://system系统层面的诊断信息汇总chrome://histograms内部指标直方图排查性能异常时用得上chrome://tracing手动抓取一段时间的详细运行轨迹chrome://version里的命令行字段特别值得看。它能告诉你当前浏览器到底带了哪些启动参数有些问题就是被某个陈旧的启动参数导致的看这里一目了然。4.3 命令行参数实测改进程模型的几种方式Chromium 暴露了一批控制进程模型的开关做实验的时候可以试试。注意这些参数不适合日常使用只用于验证理解# 让所有标签页各用一个渲染进程能明显看到进程数变多 chrome --process-per-tab # 同一个站点复用进程进程数会明显减少 chrome --process-per-site # 限制渲染进程总数上限 chrome --renderer-process-limit4 # 关闭沙箱仅限测试环境切勿日常使用 chrome --no-sandbox # 关闭硬件加速观察 GPU 进程是否消失 chrome --disable-gpu实测下来--process-per-tab的效果最直观开五个标签页任务管理器里立刻多出好几个渲染进程。--process-per-site相反访问同一站点的多个页面会共享一个进程数量明显收敛。这两个开关的对比能帮你彻底搞明白进程边界是怎么划的。提示做这类实验建议用一个独立的用户数据目录避免影响你的正常配置文件。可以在参数里加--user-data-dir指定的空目录来隔离。5. 六个进程之外的追问数量为什么忽多忽少理解了基础模型很多日常困惑就能自己解释。这一节挑几个最常见的问题说说。5.1 进程池与进程复用Chrome 不会每次都新建进程Chromium 内部维护着渲染进程的复用逻辑。当某个标签页关闭后它的渲染进程不一定立刻销毁可能被留在池子里等待下一次同站点的导航复用。这是为什么你关闭标签页后进程数没有立刻下降过一会儿再看才减少。这个过一会儿不是玄学是 Chrome 在观察后续是否有导航需求。如果你在这期间又打开了同一个站点它就直接复用了现成的进程速度会明显快一些。这种设计在体验上是加分项但在观测上会让人误以为进程残留了。5.2 扩展、iframe 与 Worker 对进程数的影响扩展是进程数增加的一大来源。每个开启的扩展都可能在后台跑自己的渲染进程或服务工作线程装了十几个扩展的用户进程数比干净安装翻一倍并不稀奇。想确认是不是扩展导致的开一个无痕窗口对比一下就能看出来因为无痕默认不加载大多数扩展。iframe 的影响也不小。在站点隔离下如果页面里嵌了跨站 iframe通常需要额外的渲染进程来承载。所以一个看起来只有一个页面的标签实际可能对应三四个进程。Web Worker 和 Service Worker 虽然跑在线程里但它们的存储访问会牵动存储服务进程间接影响资源占用。判断方法很直接打开内置任务管理器看有没有进程的页面字段显示为某个扩展名。有的话就是扩展在占资源。5.3 有进程没窗口这类现象怎么排查偶尔会遇到任务管理器里躺着一堆浏览器进程但桌面上没有任何窗口。这种情况通常是三类原因之一一是浏览器设置了关闭窗口后继续运行后台应用进程留着是为了推送和后台任务二是有扩展或后台页面在维持进程存活三是上次退出时没清理干净留下了一些孤儿进程。排查顺序建议这样先看设置里有没有开启后台运行有的话关掉再观察然后开一个无痕窗口对比确认是否与扩展相关如果怀疑是残留可以在内置任务管理器里看这些进程是否有页面关联没有关联又没有内存增长趋势的基本可以安全结束。5.4 内存和 CPU 占用怎么定位到具体进程定位资源异常内置任务管理器依然是第一选择。它的 CPU 列会自动排序哪个进程在持续吃 CPU 一眼就能看到。常见的几种情况处理方式不太一样渲染进程持续高 CPU多半是页面里的动画或脚本在跑可以直接关掉那个标签页验证。GPU 进程高 CPU 或高内存可能是某个页面的合成层过多或者显卡驱动有问题去chrome://gpu确认硬件加速状态。主进程高 CPU通常和大量标签页、大量扩展的调度有关减少两者是最有效的办法。系统任务管理器也能用但要配合命令行列或者进程树视图才能分清角色操作成本比内置的高不少。6. 几个我踩过的坑和顺手的小技巧最后说几个实际遇到过、资料里不太会写的东西。第一个坑是盲目杀进程。早年我看到一堆同名进程随手在系统任务管理器里结束了一个结果某个标签页直接崩溃恢复之后表单数据全丢了。后来才明白渲染进程和标签页是一对一或一对多的关系杀它等于杀那个页面。要结束资源占用异常的进程一定用内置任务管理器看清楚对应的页面再动手。第二个坑是把 GPU 进程当成异常。有段时间我发现 GPU 进程占了不小内存以为是泄漏到处找解决方案。后来搞清楚它在缓存合成层和纹理页面越复杂占用越高属于正常范围。真正该关注的是它是否持续攀升不回落而不是绝对值高低。第三个坑是在低配机器上硬撑着开硬件加速。老机器上显卡驱动不完善硬件加速反而导致滚动卡顿和额外耗电。关掉之后进程数少一个续航也好了。这个取舍没有标准答案得结合实际机型试。几个顺手可用的小技巧用--user-data-dir起一个独立的实验环境随便折腾不影响主配置遇到怪异问题时先看chrome://version的命令行字段经常能发现历史遗留的参数怀疑扩展时开无痕对比比一个个禁用扩展快得多。这些都是在反复折腾里攒下来的比任何文档都直接。至于六个这个数字我现在的态度是它只是个入口真正有价值的是背后那套按职责拆进程、按站点划边界的思路。理解了这套思路进程数是六个还是十个你都能自己判断出正不正常。
返回列表