每站点一个进程:一句话讲完的故事
Chromium把浏览器拆成许多操作系统进程:标签页的渲染进程每个站点一个(站点隔离让同一个标签页里的不同站点也进不同进程),再加GPU进程、网络服务、存储服务,以及每个已加载扩展各一个进程。目的在于止损——渲染进程崩溃只带走一个标签页而不是整个浏览器,被攻陷的渲染进程也无法直接访问其他站点。代价是每个进程都背负自己的运行时开销:打开二十个站点,就是二十个小小的Chromium实例,各自带着自己的那份库、JIT堆和渲染缓冲区。
数字涨得比人们预想的快,因为它从来不只是标签页:
- 每个站点一个渲染进程——十个标签页里的十个站点,再加上从其他域名iframe进来的那些
- 每个启用的扩展都跑着自己的后台进程,闲着也不例外
- GPU进程装着解码后的图像、图块和视频帧——4K YouTube标签页吃掉的大部分就是它
- service worker在标签页关闭后仍然存活,让离线应用随时待命
- 地址栏建议的预加载页面和预渲染,在你还没访问之前就占好了内存
Chrome为什么不把内存还回去
第二个原因是Chromium的分配器PartitionAlloc:它把释放掉的页面缓存在各个进程内部以便立即复用,而不是交还Windows。任务管理器会把这块缓存池显示成Chrome占用的一部分,哪怕它技术上是空闲的——所以这个数字看起来比系统实际承受的压力吓人得多。浏览器在真正的压力下确实会释放内存——关掉一个吃内存的大应用后Chrome“缓过来”就是这个道理——但在空闲的机器上,它会故意握着自己付过钱的东西。
被占住的那部分内存里,有些是名副其实的缓存:前进/后退缓存保留着已渲染的页面,让后退按钮瞬间响应;磁盘缓存映射免去了重新读文件。这也是连开好几天的浏览器比刚启动的看起来更重的原因——它只是缓存了更多值得留住的东西而已。这就是那句“闲置内存就是浪费内存”的论调,而这一次它在技术上是对的——否则每重访一个页面都得从头渲染。
真正能压缩占用的做法
先在 chrome://settings/performance 打开内存节省程序:它让非活动标签页休眠并释放其渲染进程——在多标签页会话里,这是效果最大的一个杠杆。然后排查真正的元凶:按 Shift+Esc 打开Chrome自带的任务管理器,按内存排序——多数时候,一个重型网站(Web IDE、视频会议、臃肿的网页邮箱)或一个扩展,比四十个普通标签页加起来还重。扩展尤其值得重点怀疑:每个扩展都会往每个窗口里加一个进程,而且许多在持续运行。
再往后,诚实的答案就是算术而不是魔法:少一点休眠标签页、少一点扩展、别再永久固定没人看的仪表盘。切换硬件加速是用GPU内存换CPU负载——在弱的核显上有时划算,有时正好相反。不管用的是那些强行裁剪工作集的“内存清理”工具——数字是降下来了,浏览器却在重新取回被裁剪内容时一路卡顿。
常见问题与解答
Chrome为什么要用这么多内存?
为了安全和崩溃隔离,它为每个站点运行独立进程,而它的分配器会把释放的内存留在这些进程里以便立即复用。任务管理器里的数字,还包含Chrome技术上留作备用的那部分内存。
怎么让Chrome少用点内存?
在 chrome://settings/performance 启用内存节省程序,删掉不用的扩展,再用 Shift+Esc 查清到底是哪个网站或扩展在吃内存。少开标签页,胜过任何调整。
继续阅读
联系我们: [email protected]