Chrom 的多進程架構

來源:互聯網
上載者:User

多進程架構(原文地址:http://www.chromium.org/developers/design-documents/multi-process-architecture )

這篇文檔描述了 Chromium 的上層架構。

a、問題所在

幾乎沒可能建立一個永遠不崩潰或掛機的渲染引擎,也不可能建立一個完美安全的渲染引擎。

某些方面來說,現在的 Browser 有點像過去的單使用者,多任務的作業系統。在那樣的作業系統裡,如果有一個胡作非為的程式,將會讓整個系統崩潰。也就像一個胡作非為的頁面、或外掛程式錯誤,就能帶來整個瀏覽器和當前啟動並執行所有標籤的崩潰。

現在的作業系統強壯多了,因為他們將應用程式劃分到一個個的獨立進程中,這些進程間獨立運行,不互相影響,一個程式中的crash一般不會影響到別的應用程式或者整個系統,而且某使用者要訪問別的使用者的資料也是不允許的。

b、架構概覽

主進程,也叫做 "Browser" 進程,運行UI 和管理tab。

同樣的,tab進程叫做 "Render" 進程,使用 web-kit 排布引擎來解析和排布 HTML。

c、管理多個Render 進程

每個Render 進程都有一個全域的 RenderProcess 對象管理和父進程(Browser)間的通訊以及全域的狀態,Browser對每個RenderProcess都維護了一個對應的 RenderProcessHost,用來管理 Browser 的狀態和用於通訊。Browser 和 Renderer 之間的通訊使用 Chromium's IPC system。

d、管理檢視

每個Render 進程都有一個或者多個的RenderView對象,這些對象都由RenderProcess管理,RenderView對應著每個 Tab的內容。

對應的 RenderProcessHost 維護著一個 RenderViewHost 對象,這個對象對應著每個 Renderer裡的view。

每個 view 擁有一個 viewID,這個viewID是用來區分一個renderer裡的多個不同的view,並且這些id在一個 renderer進程中是唯一的,但在整個Browser 中不是唯一的,所以要區分一個view需要一個RenderProcessHost和一個View ID。

從Browser到指定的tab內容之間的通訊是通過這些 RenderViewHost 對象來完成的,這些RenderViewHost對象知道怎麼把訊息通過 RenderProcessHost 傳到 RenderProcess ,然後再傳到 RenderView。

e、組件和介面

在 Render 進程中:

  • RenderProcess 處理 IPC 是通過Browser 中對應的 RenderProcessHost,每個render 進程都只有一個RenderProcess,這就是browser和render的通訊路徑了。
  • RenderView 對象和 Browser 中對應的RenderViewHost通訊(通過 RenderProcess),RenderView 對象也和我們的WebKit 嵌入層通訊。這個對象代表tab或視窗裡的頁面內容。

在Browser 進程中:

  • Browser對象代表最高層的瀏覽器視窗。
  • RenderProcessHost對象代表browser 端,browser和renderView的通訊,每個render 進程只有一個 RenderProcessHost。
  • RenderViewHost 對象封裝了和 RenderView 的通訊。
  • browser中的RenderWidgetHost 處理RenderWidget的輸入和繪畫。

f、共用render進程

一般來說,一個新視窗或者一個新tab,就會建立一個新進程,並建立一個RenderView,但有時候,可能要多個tab共用一個Render進程。

一個web應用開啟一個新視窗的時候,他是期待一個同步的通訊的,比如javascript的 window.open,這個情況下,我們需要在新開的視窗中重用這個進程。

我們也有辦法讓一個新的tab指向一個已存在的render進程,這種情形是用於進程太多的情況,或者使用者已經有一個進程開啟導航到網域名稱。這些辦法你可以查看這裡(http://www.chromium.org/developers/design-documents/process-models )。

g、監測崩潰和胡作非為的renderer

每個IPC串連到browser進程, browser進程都會監測進程的控制代碼。

如果這些控制代碼激發,render進程已經崩潰並且tabs被告知這個崩潰。到現在為止,我們會顯示一個“sad tab”的頁面,通知使用者,這個renderer已經崩潰了。點擊reload按鈕可以讓這個頁面重新裝載,或者開啟一個新的導航。當這個發生,我們會通知已經沒有進程,並會建立一個新的。

h、讓renderer變成一個沙箱

假設Webkit運行在一個單獨的進程中,我們可以限制它訪問系統資源。例如我們可以讓這個renderer只是通過他的父進程browser訪問網路,同樣的,我們可以通過作業系統的許可權系統來限制它訪問檔案系統。

除了限制renderer訪問檔案系統和網路,我們還可以限制它訪問使用者的顯示和相關的對象。我們每個render進程都運行在一個看不到的視窗裡,這個視窗是獨立的,叫做“Desktop”,這可以阻止一個“危險的”renderer(被植入危險的代碼)開啟一個新window或者截取你的鍵盤點擊。

i、把記憶體還回去

正因為renderer運行在一個單獨的進程中,所以我們需要考慮隱藏的tabs的低優先順序問題。

正常的,windows會把一個最小化的進程自動放進一個“有效記憶體池”中,當這個進程處於 low-memory 狀態,windows 將把這個記憶體存放到硬碟中,直到他們變為higher-priority的記憶體。

為了讓使用者可見的程式更良好的反應,我們可以把這個原則用於“隱藏”的tabs,當一個renderer不是最進階別的tab時,我們可以釋放那個進程的 “working set”大小,作為對系統的暗示,以便系統能把它的記憶體轉放到硬碟上(如果系統認為需要的話)。

因為我們發現,減少working set 的大小,也會降低tab切換的效能。當使用者在兩個tabs之間切換,我們漸漸的釋放記憶體。這意味著,如果使用者切換回最近使用的標籤,該標籤的記憶體是更可能被頁面化(存到disk)的,而少用的tab反而不會被頁面化。

當然,有足夠記憶體的使用者不用管這個,因為windows只回收他需要的資料,所以如果記憶體足夠,這樣做對效能沒有一點的好處。

這有助於我們在低記憶體的情況下得到更最佳化的記憶體佔用,少用的tab將會被完全從記憶體替換到硬碟,而前端的tab,將可以整個裝載進來記憶體中。相比之下,一個單進程的瀏覽器將其所有的tab資料隨機的分發到記憶體中,這樣就沒辦法把使用或者不實用的資料分離得那麼清晰,這樣就浪費記憶體以及效能了。

j、外掛程式

Firefox風格的 NPAPI 外掛程式會運行在他自己的進程中,和renderer隔開。具體可以看這裡:http://www.chromium.org/developers/design-documents/plugin-architecture 。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.