從本質(zhì)上說(shuō),進(jìn)程和線(xiàn)程都是 CPU 工作時(shí)間片的一個(gè)描述:進(jìn)程描述了 CPU 在運(yùn)行指令及加載和保存上下文所需的時(shí)間,放在應(yīng)用上來(lái)說(shuō)就代表了一個(gè)程序。線(xiàn)程是進(jìn)程中的更小單位,描述了執(zhí)行一段指令所需的時(shí)間。進(jìn)程是資源分配的最小單位,線(xiàn)程是CPU調(diào)度的最小單位。
一個(gè)進(jìn)程就是一個(gè)程序的運(yùn)行實(shí)例。詳細(xì)解釋就是,啟動(dòng)一個(gè)程序的時(shí)候,操作系統(tǒng)會(huì)為該程序創(chuàng)建一塊內(nèi)存,用來(lái)存放代碼、運(yùn)行中的數(shù)據(jù)和一個(gè)執(zhí)行任務(wù)的主線(xiàn)程,我們把這樣的一個(gè)運(yùn)行環(huán)境叫進(jìn)程。進(jìn)程是運(yùn)行在虛擬內(nèi)存上的,虛擬內(nèi)存是用來(lái)解決用戶(hù)對(duì)硬件資源的無(wú)限需求和有限的硬件資源之間的矛盾的。從操作系統(tǒng)角度來(lái)看,虛擬內(nèi)存即交換文件;從處理器角度看,虛擬內(nèi)存即虛擬地址空間。
如果程序很多時(shí),內(nèi)存可能會(huì)不夠,操作系統(tǒng)為每個(gè)進(jìn)程提供一套獨(dú)立的虛擬地址空間,從而使得同一塊物理內(nèi)存在不同的進(jìn)程中可以對(duì)應(yīng)到不同或相同的虛擬地址,變相的增加了程序可以使用的內(nèi)存。
進(jìn)程和線(xiàn)程之間的關(guān)系有以下四個(gè)特點(diǎn):
(1)進(jìn)程中的任意一線(xiàn)程執(zhí)行出錯(cuò),都會(huì)導(dǎo)致整個(gè)進(jìn)程的崩潰。
(2)線(xiàn)程之間共享進(jìn)程中的數(shù)據(jù)。
(3)當(dāng)一個(gè)進(jìn)程關(guān)閉之后,操作系統(tǒng)會(huì)回收進(jìn)程所占用的內(nèi)存, 當(dāng)一個(gè)進(jìn)程退出時(shí),操作系統(tǒng)會(huì)回收該進(jìn)程所申請(qǐng)的所有資源;即使其中任意線(xiàn)程因?yàn)椴僮鞑划?dāng)導(dǎo)致內(nèi)存泄漏,當(dāng)進(jìn)程退出時(shí),這些內(nèi)存也會(huì)被正確回收。
(4)進(jìn)程之間的內(nèi)容相互隔離。 進(jìn)程隔離就是為了使操作系統(tǒng)中的進(jìn)程互不干擾,每一個(gè)進(jìn)程只能訪問(wèn)自己占有的數(shù)據(jù),也就避免出現(xiàn)進(jìn)程 A 寫(xiě)入數(shù)據(jù)到進(jìn)程 B 的情況。正是因?yàn)檫M(jìn)程之間的數(shù)據(jù)是嚴(yán)格隔離的,所以一個(gè)進(jìn)程如果崩潰了,或者掛起了,是不會(huì)影響到其他進(jìn)程的。如果進(jìn)程之間需要進(jìn)行數(shù)據(jù)的通信,這時(shí)候,就需要使用用于進(jìn)程間通信的機(jī)制了。
Chrome瀏覽器的架構(gòu)圖:
從圖中可以看出,最新的 Chrome 瀏覽器包括:1 個(gè)瀏覽器主進(jìn)程1 個(gè) GPU 進(jìn)程1 個(gè)網(wǎng)絡(luò)進(jìn)程多個(gè)渲染進(jìn)程多個(gè)插件進(jìn)程這些進(jìn)程的功能:瀏覽器進(jìn)程:主要負(fù)責(zé)界面顯示、用戶(hù)交互、子進(jìn)程管理,同時(shí)提供存儲(chǔ)等功能。
渲染進(jìn)程:核心任務(wù)是將 HTML、CSS 和 JavaScript 轉(zhuǎn)換為用戶(hù)可以與之交互的網(wǎng)頁(yè),排版引擎 Blink 和 JavaScript 引擎 V8 都是運(yùn)行在該進(jìn)程中,默認(rèn)情況下,Chrome 會(huì)為每個(gè) Tab 標(biāo)簽創(chuàng)建一個(gè)渲染進(jìn)程。出于安全考慮,渲染進(jìn)程都是運(yùn)行在沙箱模式下。
GPU 進(jìn)程:其實(shí), GPU 的使用初衷是為了實(shí)現(xiàn) 3D CSS 的效果,只是隨后網(wǎng)頁(yè)、Chrome 的 UI 界面都選擇采用 GPU 來(lái)繪制,這使得 GPU 成為瀏覽器普遍的需求。最后,Chrome 在其多進(jìn)程架構(gòu)上也引入了 GPU 進(jìn)程。
網(wǎng)絡(luò)進(jìn)程:主要負(fù)責(zé)頁(yè)面的網(wǎng)絡(luò)資源加載,之前是作為一個(gè)模塊運(yùn)行在瀏覽器進(jìn)程里面的,直至最近才獨(dú)立出來(lái),成為一個(gè)單獨(dú)的進(jìn)程。
插件進(jìn)程:主要是負(fù)責(zé)插件的運(yùn)行,因插件易崩潰,所以需要通過(guò)插件進(jìn)程來(lái)隔離,以保證插件進(jìn)程崩潰不會(huì)對(duì)瀏覽器和頁(yè)面造成影響。所以,打開(kāi)一個(gè)網(wǎng)頁(yè),最少需要四個(gè)進(jìn)程:1 個(gè)網(wǎng)絡(luò)進(jìn)程、1 個(gè)瀏覽器進(jìn)程、1 個(gè) GPU 進(jìn)程以及 1 個(gè)渲染進(jìn)程。如果打開(kāi)的頁(yè)面有運(yùn)行插件的話(huà),還需要再加上 1 個(gè)插件進(jìn)程。雖然多進(jìn)程模型提升了瀏覽器的穩(wěn)定性、流暢性和安全性,但同樣不可避免地帶來(lái)了一些問(wèn)題:更高的資源占用:因?yàn)槊總€(gè)進(jìn)程都會(huì)包含公共基礎(chǔ)結(jié)構(gòu)的副本(如 JavaScript 運(yùn)行環(huán)境),這就意味著瀏覽器會(huì)消耗更多的內(nèi)存資源。
更復(fù)雜的體系架構(gòu):瀏覽器各模塊之間耦合性高、擴(kuò)展性差等問(wèn)題,會(huì)導(dǎo)致現(xiàn)在的架構(gòu)已經(jīng)很難適應(yīng)新的需求了。