Chromium多進程架構


原文地址:http://www.chromium.org/developers/design-documents/multi-process-architecture


1、多進程架構

瀏覽器引擎不可能絕對穩定,也不可能絕對安全。

某種程度上,當前的Web瀏覽器類似於之前單用戶、多任務協同工作的操作系統。

現代操作系統使用不同的進程將不同的應用隔離起來,因而更加健壯。一個應用程序的的崩潰一般不會影響其他應用程序,也不會影響操作系統的完整,而且用戶對其他用戶數據的訪問受到限制。

2、結構概述

爲了減少瀏覽器內核的bug,我們將不同的Tab頁用不同的進程隔離起來。進程間的訪問受限,對系統其他部分的訪問也受限。這使得web瀏覽器獲得了類似內存保護和訪問控制給操作系統帶來的好處。

我們將UI和管理Tab頁、插件進程的主進程稱爲browser進程或者browser。同樣的,一個特定tab頁對應的進程被稱爲render進程或者renderers。這些renderers使用WebKit開源佈局引擎來解釋和佈局HTML。



4、管理視圖

每個Render進程有一個或多個RenderView對象,通過Render裏的全局對象 RenderProcess管理,對應着tab頁裏的內容。
Browser裏的RenderProcessHost 爲每一個View維護一個RenderViewHost用ID號來標識同一個Render裏不同的View。ID值在一個Render裏是不同的,但不保證在Browser裏不同,所以要需要一個RenderProcessHost和一個ViewID才能定位到一個View。Browser和特定tab頁裏的特定view通過這些RenderProcessHost對象來通信,它們知道怎樣從RenderProcessHost發送消息到 RenderProcess並最終作用於RenderView


5、組件和接口

在render進程裏
  • RenderProcess(Render端)維持着與RenderProcessHostBrowser端)間IPC通信。每個render進程只有一個RenderProcess對象,這就是browser和所有的renderers間通信的方式。
  • Renderview(Render端)通過RenderProcess(Render端)以及WebKit嵌入層RenderViewHost (Browser端)通信。Renderview對象代表一個tab頁的內容或者一個彈出窗口。

在browser進程裏
  • Browser對象代表一個最高級別的的瀏覽器窗口。
  • RenderProcessHostBrowser端)對象代表一個 Browser和Renderer間的IPC連接。每個render進程對應browser進程裏的一個RenderProcessHost
  • RenderViewHostBrowser端)對象將同遠端Renderview(Render端)的通信封裝進內部,RenderWidgetHostBrowser端)對象控制着RenderWidget(Render端)的輸入和繪製。

可以在How Chromium displays web pages 設計文檔裏查看更詳細的內容。

6、共享render進程

一般來說,每個新的窗口或者tab頁在一個新的進程裏創建。Browser會產生一個新的進程並指導它創建一個 RenderView(Render端)。

有時,在tab頁或者窗口間需要共享render進程。一個web應用創建了一個新的窗口,想和它同步通信,例如使用JavaScript的window.open。這種情況下,當我們創建一個新的窗口或者tab頁,需要重用這個窗口的進程。當總線程個數太大的或者已經有導航到那個域名的進程的時候,我們需要一種策略將新的tab頁綁定到已經存在的進程裏。這些策略在Process Models有詳細描述。

7、探測未正常運行的Renderers

每個同browser進程的IPC連接都會監聽進程句柄。句柄指示異常表示render進程崩潰,tab頁能感知到這種異常。目前,我們用一個崩潰頁面告訴用戶這個進程已經崩潰。可以通過點擊重新加載按鈕或者開啓新的導航來重新加載頁面。這樣的操作發生時我們會發現沒有對應的進程並創建一個新的。

8、將renderer放入沙盒

考慮到Webkit在單獨的進程裏運行,我們有機會限定它對系統資源的訪問。例如,我們能保證renderer對網絡的訪問是通過父browser進程完成的。同樣的,我們也可以使用操作系統內置的許可限制render對文件系統的訪問。
除了限制renderer對文件系統和網絡的訪問,我們也可以給它對用戶顯示和相關對象的訪問加上權限。每個線程可以在其他線程不可見的系統桌面上運行。這阻止了被盜用的renderer開啓窗口或者捕獲按鍵。

9、內存回收

Renderers在不同的線程中運行,自然而然將隱藏的tab頁置爲低優先級。通常,Windows操作系統將進程內存放入“可用內存”池來減少內存佔用。在內存吃緊的情況下,WIndows會將低優先級的內存置換到硬盤,確保用戶可見的程序交互更順暢。我們可以將這種規則應用到隱藏的tab頁中。如果必要,當一個render進程沒有高級別tab頁的時候,可以暗示操作系統將render的工作集內存置換到硬盤裏。我們逐漸的釋放這些內存,因爲工作集內存的釋放幫隨着切換tab頁性能變差的後遺症。這意味着,用戶切回剛用過的標籤頁比切回很久沒有使用的標籤頁工作集內存準備好的機率更高。如果用戶有足夠的內存跑起來所有的程序,將不會進行內存置換。

Windows只在必要的時候這麼做,所以內存足夠的時候將不會有性能憂慮。

這幫助我們在低內存環境有一個更優化的內存佔用模式。幾乎不用的低級別標籤頁內存可以置換出去,而高級別標籤頁的數據可以完全加載到內存中。相比之下,單進程瀏覽器將所有選項卡的數據隨機分配到內存,幾乎沒有可能完全分離未用和已用的數據,既浪費內存又浪費性能。


10、插件

火狐風格的NPAPI插件在它們自己的進程中運行,和renderer隔離了開來,這在 Plugin Architecture裏有詳細的介紹。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章