<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          一文理解JVM線程屬于用戶態(tài)還是內(nèi)核態(tài)

          共 2570字,需瀏覽 6分鐘

           ·

          2021-06-02 12:38

          Linux操作系統(tǒng)的體系架構(gòu)分為用戶態(tài)和內(nèi)核態(tài)(或者用戶空間和內(nèi)核)。

          用戶態(tài)與內(nèi)核態(tài)

          內(nèi)核從本質(zhì)上看是一種軟件——控制計算機(jī)的硬件資源,并提供上層應(yīng)用程序運(yùn)行的環(huán)境。用戶態(tài)即上層應(yīng)用程序的活動空間,應(yīng)用程序的執(zhí)行必須依托于內(nèi)核提供的資源,包括CPU資源、存儲資源、I/O資源等。

          注:對操作系統(tǒng)來說,用戶態(tài)線程具有不可見性,也稱透明性。

          1. 用戶態(tài)線程調(diào)度完全由進(jìn)程負(fù)責(zé),通常就是由進(jìn)程的主線程負(fù)責(zé)(用戶可以為應(yīng)用程序定制調(diào)度算法),相當(dāng)于進(jìn)程主線程的延展,使用的是操作系統(tǒng)分配給進(jìn)程主線程的時間片段;內(nèi)核線程由內(nèi)核維護(hù),由操作系統(tǒng)調(diào)度。

          2. 用戶態(tài)線程無法跨核心,一個進(jìn)程的多個用戶態(tài)線程不能并發(fā),阻塞一個用戶態(tài)線程會導(dǎo)致進(jìn)程的主線程阻塞,直接交出執(zhí)行權(quán)限。這些都是用戶態(tài)線程的劣勢。內(nèi)核線程可以獨(dú)立執(zhí)行,操作系統(tǒng)會分配時間片段。

          用戶態(tài)的應(yīng)用程序可以通過三種方式來訪問內(nèi)核態(tài)的資源:

          • 系統(tǒng)調(diào)用

          • 公用函數(shù)庫

          • Shell腳本

          為什么需要區(qū)分用戶態(tài)和內(nèi)核態(tài)

          在 CPU 的所有指令中,有些指令是非常危險的,如果錯用,將導(dǎo)致系統(tǒng)崩潰,比如清內(nèi)存、設(shè)置時鐘等。如果允許所有的程序都可以使用這些指令,那么系統(tǒng)崩潰的概率將大大增加。

          所以,CPU將指令分為特權(quán)指令和非特權(quán)指令,對于那些危險的指令,只允許操作系統(tǒng)及其相關(guān)模塊使用,普通應(yīng)用程序只能使用那些不會造成災(zāi)難的指令。

          比如Intel的CPU將特權(quán)等級分為4個級別:Ring0~Ring3;Linux 系統(tǒng)只使用了Ring0和Ring3兩個運(yùn)行級別。

          當(dāng)進(jìn)程運(yùn)行在Ring3級別時被稱為運(yùn)行在用戶態(tài),而運(yùn)行在 Ring0 級別時被稱為運(yùn)行在內(nèi)核態(tài)。

          從用戶態(tài)到內(nèi)核態(tài)的切換的時機(jī)

          很多程序開始時運(yùn)行于用戶態(tài),但在執(zhí)行的過程中,一些操作需要在內(nèi)核權(quán)限下才能執(zhí)行,這就涉及到一個從用戶態(tài)切換到內(nèi)核態(tài)的過程。

          1. 系統(tǒng)調(diào)用。操作系統(tǒng)對內(nèi)核級別的指令進(jìn)行封裝,統(tǒng)一管理硬件資源,然后向用戶程序提供系統(tǒng)服務(wù),用戶程序進(jìn)行系統(tǒng)調(diào)用后,操作系統(tǒng)執(zhí)行一系列的檢查驗(yàn)證,確保這次調(diào)用是安全的,再進(jìn)行相應(yīng)的資源訪問操作。比如C函數(shù)庫中的內(nèi)存分配函數(shù)malloc(),它具體是使用sbrk()系統(tǒng)調(diào)用來分配內(nèi)存;當(dāng)malloc調(diào)用sbrk()的時候就涉及一次從用戶態(tài)到內(nèi)核態(tài)的切換;類似的函數(shù)還有printf(),調(diào)用的是wirte()系統(tǒng)調(diào)用來輸出字符串等等。

          2. 異常事件。當(dāng)CPU正在執(zhí)行運(yùn)行在用戶態(tài)的程序時,突然發(fā)生某些預(yù)先不可知的異常事件,這個時候就會觸發(fā)從當(dāng)前用戶態(tài)執(zhí)行的進(jìn)程轉(zhuǎn)向內(nèi)核態(tài)執(zhí)行相關(guān)的異常事件,如缺頁異常。

          3. 外圍設(shè)備的中斷。當(dāng)外圍設(shè)備完成用戶的請求操作后,會向CPU發(fā)出中斷信號,此時,CPU就會暫停執(zhí)行下一條即將要執(zhí)行的指令,轉(zhuǎn)而去執(zhí)行中斷信號對應(yīng)的處理程序,如果先前執(zhí)行的指令是在用戶態(tài)下,則自然就發(fā)生從用戶態(tài)到內(nèi)核態(tài)的轉(zhuǎn)換。

          注意:系統(tǒng)調(diào)用的本質(zhì)其實(shí)也是中斷,相對于外圍設(shè)備的硬中斷,這種中斷稱為軟中斷,這是操作系統(tǒng)為用戶特別開放的一種中斷。所以,從觸發(fā)方式和效果上來看,這三種切換方式是完全一樣的,都相當(dāng)于是執(zhí)行了一個中斷響應(yīng)的過程。但是從觸發(fā)的對象來看,系統(tǒng)調(diào)用是進(jìn)程主動請求切換的,而異常和硬中斷則是被動的。

          理解了這里,推薦看下《NIO效率高的原理之零拷貝與直接內(nèi)存映射》中有關(guān)NIO零拷貝優(yōu)化的知識。

          用戶線程與內(nèi)核線程的映射關(guān)系

          用戶線程一般不會直接去使用內(nèi)核線程,而是去使用內(nèi)核線程的一種高級接口——輕量級進(jìn)程(Light Weight Process,LWP)。因此對于用戶線程來說,用戶程序必須讓它的調(diào)度器采用用戶線程,然后在內(nèi)核線程上運(yùn)行它。

          用戶線程與內(nèi)核線程的映射關(guān)系有三種模型:一對一模型、多對一模型、多對多模型。

          一對一模型

          有了內(nèi)核線程,每個用戶線程被映射到一個內(nèi)核線程。用戶線程在其生命期內(nèi)都會映射到該內(nèi)核線程。一旦用戶線程終止,兩個線程都將離開系統(tǒng)。這被稱作"一對一"線程映射。

          缺點(diǎn):

          1. 操作系統(tǒng)限制了內(nèi)核線程的數(shù)量,因此一對一模型會使用戶線程的數(shù)量受到限制。

          2. 操作系統(tǒng)內(nèi)核線程調(diào)度時,上下文切換的開銷較大,導(dǎo)致用戶線程的執(zhí)行效率下降。

          多對一模型

          多對一模型將多個用戶線程映射到一個內(nèi)核線程上,線程之間的切換由用戶態(tài)的代碼來進(jìn)行,因此相對一對一模型,多對一模型的線程切換速度要快許多。此外,多對一模型對用戶線程的數(shù)量幾乎無限制。

          缺點(diǎn):

          1. 如果其中一個用戶線程阻塞,那么其它所有線程都將無法執(zhí)行,因?yàn)榇藭r內(nèi)核線程也隨之阻塞了。

          2. 在多處理器系統(tǒng)上,處理器數(shù)量的增加對多對一模型的線程性能不會有明顯的增加,因?yàn)樗械挠脩艟€程都映射到一個處理器上了。

          多對多模型

          多對多模型(又稱為M對N模型)結(jié)合了一對一模型和多對一模型的優(yōu)點(diǎn),將多個用戶線程映射到多個內(nèi)核線程上。

          優(yōu)點(diǎn):

          1. 一個用戶線程的阻塞不會導(dǎo)致所有線程的阻塞,因?yàn)榇藭r還有別的內(nèi)核線程被調(diào)度來執(zhí)行。

          2. 多對多模型對用戶線程的數(shù)量沒有限制。

          3. 在多處理器的操作系統(tǒng)中,多對多模型的線程也能得到一定的性能提升,但提升的幅度不如一對一模型的高。在現(xiàn)在流行的操作系統(tǒng)中,大都采用多對多的模型。

          JVM線程屬于用戶態(tài)還是內(nèi)核態(tài)

          java線程在jdk1.2之前,是基于名為“綠色線程”的用戶線程實(shí)現(xiàn)的,這導(dǎo)致綠色線程只能同主線程共享CPU分片,從而無法利用多核CPU的優(yōu)勢。

          由于綠色線程和原生線程比起來在使用時有一些限制, jdk1.2中放棄綠色線程,轉(zhuǎn)而使用原生線程。

          在目前的jdk版本中,操作系統(tǒng)支持怎樣的線程模型,很大程度上決定了java虛擬機(jī)的線程是怎樣映射的,這點(diǎn)在不同的平臺上都沒有辦法達(dá)成一致。

          總的來說就是,虛擬機(jī)規(guī)范中并沒有限定java線程需要使用哪種線程模型,要根據(jù)不同的平臺來說,但是無論使用哪種線程模型,java程序的編碼和運(yùn)行都是沒有差異的。

          例如,Java SE最常用的JVM是Oracle/Sun研發(fā)的HotSpot VM。在這個JVM所支持的所有平臺上都是采用一對一的線程模型的,除了Solaris平臺。

          參考文檔:

          1. 《深入理解Java虛擬機(jī)》


          瀏覽 71
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  啪啪福利视频 | 九一九国产 | 天天干夜操 | 国产做受 高潮游戏视频 | 可以免费看的A片 |