天天看點

為什麼浏覽器采用多程序模型為什麼浏覽器采用多程序模型多程序 vs. 多線程浏覽器對多程序的需求關于性能單程序的Android WebView性能差嗎參考:

這個問題的答案似乎是非常清楚的,可以概括為:為了安全、穩定、性能,隻是要犧牲點記憶體作為代價。對于安全和穩定,利用系統的程序機制就可以完成。但是多程序下的程序間通訊(IPC)很慢,而分為多程序後,一些協作任務就要分開到兩個程序,如何能保持良好的性能,更不說比單程序模型更高的性能了? 是以這裡再次探讨浏覽器選擇多程序架構的原因,以及對應架構中的要點。

先了解一下背景。将工作并行處理,是提高性能的手段。這個工作涉及到硬體,作業系統和應用程式。我不性硬體,隻知道核是越來越多,線程的處理能力也是越來越強。從系統的角度來看,似乎可以響應并行處理的資源越來越充分。是以研究如何在多核的時代提高應用的性能是目前的一大熱點。Intel和IBM都有大量關于并行及并發處理的資料和工具。

無論是多線程,還是多程序,其目的都是充分利用系統的核心資源,如CPU, I/O, GPU及記憶體等相關的資源,使得任務盡可能的并行完成,以改善應用的響應性能,提高吞吐量。對單個應用而言,其關鍵是解決并發(Concurrency)的問題 (同時跑多個應用是并行處理的問題)。即找到平衡任務和資料依賴的最佳設計,從系統的角度看主要面臨兩個挑戰:

1. 系統資源的競争。如記憶體,檔案系統等。

2. 上下文切換。

線程和程序都有上下文切換的開銷。但在多核下,程序的上下文開銷開始降低。

而從應用程式設計的角度來看,還有兩點:

1. 降低任務依賴。比如執行操作的先後順序問題。

2. 降低資料依賴。比如某個資料的修改和使用會影響到多個任務。

上面所列的四個問題中,無論是多程序,還是多線程都要面對。其中多程序在上下文切換的開銷上有先天優勢。

多程序在安全性和穩定性上優于多線程模型,一是現代系統都有程序的安全機制,特别是沙箱機制。另外單個程序有獨立的記憶體空間,不像多線程共享虛拟記憶體,是以不會因為一個線程的崩潰導緻整個應用的崩潰。

多程序需要面對的問題包括:

1. 記憶體占用大,因為無法像多線程模型共享公共的記憶體開銷,比如使用的庫,或者某些全局的資料緩存等。這是硬傷。

2. 程序間通訊的成本大。特别是使用共享記憶體交換資料的成本。

3. 程序啟動的開銷大。

後面兩個是性能問題,與前一個并不相同。而且,随着記憶體配置不斷高升,再配合一些記憶體優化的手段,比如OilPan, 第一個問題并不算太迫切。而後面兩個問題,相對于頁面渲染的開銷,隻要限定在一定範圍,也不會有太大的影響。是以限定的規則就很重要。

決定浏覽器采用多程序架構還是多線程架構,并不是取決于性能。因為從上面的分析也能看出來,多程序模型和多線程模式相比,隻要将IPC和啟動的開銷降低,其性能的高低仍然取決于各個程序中的線程設計。

結合Google和Mozilla對各自采用多程序架構的說明,可以了解到促使浏覽器采用多程序架構的是越來越複雜的頁面。以下以Chromium的研究論文為主,Mozilla關于Multiprocess Firefox的說明也主要說明之前的性能優化也是可以使用多程序的方式實作的,是以不再詳細說明。

現在的頁面越來越複雜,H5, Webapp,或者Hybrid App等等,它們執行的任務越來越重,不再像以前都是文檔類型的頁面,現在的頁面更像是一個應用。它們對系統資源的需求變大,同時不穩定的機率也增大。如果同時開啟多個頁面,就會引入更長的操作延遲,嚴重影響使用者體驗。

頁面浏覽中核心的功能是頁面的渲染(從DOM Tree到Render Tree),JS的執行, 它是一個需要集中運算的功能,相對獨立于系統資源的使用。而系統資源的使用又可以集中起來共享使用,也有利于将不安全的頁面與系統資源隔離開來(沙箱機制的需求)。于是就形成了現在程序架構:

為什麼浏覽器采用多程式模型為什麼浏覽器采用多程式模型多程式 vs. 多線程浏覽器對多程式的需求關于性能單程式的Android WebView性能差嗎參考:

上面多個Renderer Engines和Plugin-in程序和一個Browser程序構成了Chromium的程序模型。

是以再結合這點思考,為什麼Chromium強調對資料庫的操作都要抛到Browser程序來完成?

我們先看一下Google論證多程序性的資料。他們當時(2009)特别選了一台雙核的電腦來進行測試,所有的加載都是從本地檔案加載,以避免網絡的影響。最終測試的性能資料對比如下:

為什麼浏覽器采用多程式模型為什麼浏覽器采用多程式模型多程式 vs. 多線程浏覽器對多程式的需求關于性能單程式的Android WebView性能差嗎參考:

Startup是啟動并且開新頁面的時間,New Tab是在新頁簽打開頁面的時間,Navigation則是頁面上打開新頁面的時間。Monolithic是單程序,另一個不用說了。

為什麼啟動并開新頁面的時間也變快了?原因當然是程序啟動引入的開銷其實是很小的,開頁面帶來的收益要遠大于它。

再看一下加載頁面到可操作及加載完成所需要的時間:

為什麼浏覽器采用多程式模型為什麼浏覽器采用多程式模型多程式 vs. 多線程浏覽器對多程式的需求關于性能單程式的Android WebView性能差嗎參考:

對于單程序模型,基本要等加載完了才能操作。而多程序模型下,頁面渲染與使用者操作能夠分别響應。當然在單程序模型,利用中斷的方式也能達到相似的效果。

這些是Chromium在對IPC和程序中系統資源操作進行嚴格限制所達到的效果。如果破壞了這些限制,性能就不見得這樣理想了。

看一下Google工程師的回複吧:

大意為有得有失,關鍵是“視情況而定”。缺點是線程競争相對嚴重了,好處是線程切換少了,性能差的手機也能跑得不錯。 引申的意思就是如果是好手機,性能還是有差距的。 還有一個他沒說的,單程序下的安全、穩定性又回到過去的狀态了,長時間使用後的記憶體碎片現象也一起回來了。

<a href="http://homes.cs.washington.edu/~gribble/papers/eurosys-2009.pdf">Isolating Web Programs in Modern Browser Architectures</a>

<a href="https://billmccloskey.wordpress.com/2013/12/05/multiprocess-firefox/">Multiprocess Firefox</a>