在使用浏览器时偶然发现虽然仅仅打开一个标签页,但是在任务管理器内发现有多个浏览器进程在运行,占用了不小的内存,当时很纳闷:为什么一个浏览器却需要多个进程呢?不经意间在网上发现这篇文章,以Googlechrome浏览器为例,讲解了使用多进程构架的浏览器。翻译给大家,希望对有英语阅读困难的同学有所帮助,第一次翻译技术文章,好多术语不明白啥意思,也没有搜到都是凭理解翻译的。如cross-siteframe,如果有错误请不吝指正。
原文地址:
http://blog.chromium.org/2008/09/multi-process-architecture.html
浏览器的多进程构架
跟现在的很多浏览器不一样,谷歌chrome浏览器使用多个进程来隔离不同的网页和你的计算机。在这篇博客中我将会解释为什么在现在的网络条件下使用多进程架构是一个巨大的进步。我还会讨论浏览器的不同部分分别属于什么进程以及在什么情况下googlechrome为创建一个新的进程。
1:为什么在一个浏览器中使用多个进程。
在浏览器刚被设计出来的时候,那时的网页非常的简单,几乎没有动态的代码。这对仅使用一个进程渲染所有要访问的网页却仍然保持非常低的资源占有率是行得通的。
然而在今天我们看到大量网页转而使用动态网页,从含有大量javascript和flash的网页到像完全成熟的网络应用如GMail。这些应用的很大一部分是在浏览器中运行的,就像运行在操作系统之上的应用程序一样。跟操作系统一样,浏览器必须让这些应用互相分离。
除此之外,浏览器中负责渲染HTML,JavaScript和CSS的部分日益的复杂。在这些渲染引擎在演化的过程中会频繁的出现bug,有些bug会导致渲染引擎崩溃。不仅如此,渲染引擎会经常性的在网络上遇到不可信、甚至是恶意的代码,它们会利用这些漏洞在你的电脑上安装恶意的软件。
在当今世界,把所有东西都放进一个进程的浏览器面临在健壮性,响应速度,安全性方面的挑战。如果浏览器中的一个网络应用崩溃的话,这回波及括所有被打开的应用在内的任何其他应用。单线程的网络应用不得不经常相互竞争以获得的cpu时间,这有时会导致整个浏览器无法响应。安全性也同样不容小觑,因为仅仅一个页面就可以利用渲染引擎的某个漏洞获得对整台计算机的控制权。
然而,并不是非这样做不可。网络应用在设计的时候就是在浏览器中相互独立且并行的运行。它们不需要对磁盘和设备的访问权。这些被应用在网络上的安全策略保证了这些,使让你在访问大部分的页面时并不需要担心数据和计算机的安全性。这意味着可以让浏览器中的应用在不破坏彼此的情况下完全相互隔离。对于浏览器中的插件如flash也是一样的,它们与浏览器松散的耦合在一起且相互隔离,这没有任何问题。
GoogleChrome充分利用了这种特性,它将插件或是网络应用放在与浏览器本身不同的进程中。在一个渲染引擎中的崩溃并不会影响浏览器本身或是其他网络应用。这意味着操作系统可以并发的运行网络应用来提高响应速度,如果一个特定的网络应用程序或是插件停止响应时浏览器本身并不会被死锁。这也意味着我们可以在一个严格意义上的沙箱内运行渲染引擎进程,帮助减少发生错误时造成的损失。
有趣的是,使用多进程意味着GoogleChrome可以有自己的任务管理器,你可以通过右击浏览器标题栏打开。这个任务管理器可以让你跟踪每个网络应用和插件的资源使用率,而不是针对整个浏览器。
它也可以让你在不需要重启浏览器的情况下终止任何停止响应网络应用或插件。
针对以上原因,GoogleChrome浏览器的多进程构架与单进程浏览器相比有更强的健壮性,更快的响应速度,同时更安全。
2:每个进程内都有什么。
GoogleChrome创建三种不同类型的进程:浏览器进程,渲染器进程,插件进程。
浏览器进程:浏览器进程只有一个,用于管理标签页、窗口和浏览器本身。这个进程同时负责处理所有跟磁盘、网络、用户输入和显示的交互,然而它不分析和渲染任何网页内容。
渲染器进程:渲染器进程会创建多个进程,每个都负责渲染网页。渲染器进程中包含用于操作HTML,JavaScript,CSS,图片和其他内容的复杂的逻辑。我们使用了也同样被AppleSafari浏览器使用的开源的WebKit渲染引擎实现以上功能。每个渲染器进程都运行在沙箱内,这意味着它对磁盘、网络和显示器没有直接的访问权限。所有跟网络应用的交互,包括用户输入事件和屏幕绘制都必须通过浏览器进程。这可以让浏览器进程监视渲染器的可疑行为,一旦发现其从事破坏活动就将其终止。
插件进程:浏览器进程同样为处于使用状态的每种类型的插件创建一个进程,如:Flash、Quicktime或Adobereader。这些进程仅仅包含插件本身以及和浏览器进程、渲染器进程交互的胶水代码。
3:在什么情况下浏览器会创建进程。
一旦GoogleChrome创建了一个浏览器进程,它一般会为你所访问的每个站点创建一个渲染器进程。这种做法旨在将不同站点的不同网页相互隔离。
你可以这样认为:浏览器对每个标签页面使用不同的进程,但是允许两个相关的且属于同一站点的网页共享同一个渲染器进程。例如,如果打开另一个也使用JavaScript的标签页,或者你打开了属于同一个站点的新标签页,这些标签页将会共享一个渲染器进程。这可以让这些标签页中的页面通过JavaScript通信,共享缓存对象。相反,如果你在标签页的地址栏里输入一个不同站点的URL,这个标签页会被交换到一个新的渲染器进程。
跟已存在的页面保持兼容对我们来讲非常重要。基于此,我们将每个站点定义一个像google.com或bbc.co.uk注册的域名,这意味着我们可以认为像mail.google.com和maps.google.com一样的子域名是属于同一个站点。这很有必要,因为存在属于不同子域名的标签页面通过Javascript相互通信的情况,因此我们让它们使用同一个渲染器进程。
然而,对这种基本的方法要有以下注意事项。如果创建太多的进程,电脑的性能会降低,因此我们限定了创建渲染进程的最大数量(大多数情况下是20)。当达到这个限制时我们会为新标签页页面重用已经存在的渲染器进程。因此,同一个渲染器进程可以被用于多个站点。我们不把跨站点的访问放在原来的进程,同时也不将所有类型的交叉站点导航都交换到新的渲染器进程。目前,我们仅仅将浏览器进程本身的导航交换到新的标签页进程。尽管有这么多告诫,在平常使用时googlechrome还是会将不同站点相互隔离。
对于每一种类型的插件,当你第一次访问一个使用该插件的网页时,googlechrome会创建一个插件进程。只有当所有使用该插件的所有网页都被关闭之后,该进程才会被撤销。
随着我们对创建和交换渲染器进程策略的进一步细化,我们会发布更多的博客。同时我们希望在你使用Googlechrome时会体验到多进程构建带来的诸多好处。
本文由CharlieReis发表
ithzhang翻译
转载请注明出处,谢谢!!