學(xué)習(xí)此篇文章需要
先學(xué)習(xí)java內(nèi)存基礎(chǔ)
再學(xué)習(xí)JVM8基礎(chǔ)結(jié)構(gòu)圖理解
1 CPU模型
去過機(jī)房的同學(xué)都知道埋心,一般在大型服務(wù)器上會配置多個CPU含长,每個CPU還會有多個核栏妖,這就意味著多個CPU或者多個核可以同時(并發(fā))工作
1.1 CPU Register
CPU Register
也就是 CPU 寄存器
景醇。CPU寄存器
是 CPU
內(nèi)部集成的攒驰,在寄存器上執(zhí)行操作的效率要比在主存上高出幾個數(shù)量級
在CPU
中至少要有六類寄存器:指令寄存器(IR)疫粥、程序計數(shù)器(PC)、地址寄存器(AR)腰懂、數(shù)據(jù)寄存器(DR)梗逮、累加寄存器(AC)、程序狀態(tài)字寄存器(PSW)绣溜。這些寄存器用來暫存一個計算機(jī)字慷彤,其數(shù)目可以根據(jù)需要進(jìn)行擴(kuò)充
按與CPU遠(yuǎn)近來分
,離得最近的是寄存器
怖喻,然后緩存
底哗,最后內(nèi)存
。所以锚沸,寄存器是最貼近CPU
的跋选,而且CPU只與寄存器中進(jìn)行存取。寄存器從內(nèi)存中讀取數(shù)據(jù)哗蜈,但由于寄存器和內(nèi)存讀取速度相差太大前标,所以有了緩存
。即讀取數(shù)據(jù)的方式為:
CPU <------> 寄存器 <----> 緩存 <-----> 內(nèi)存
當(dāng)寄存器沒有從緩存中讀取到數(shù)據(jù)時距潘,也就是沒有命中炼列,那么就從內(nèi)存中讀取數(shù)據(jù)
1.2 CPU Cache Memory
CPU Cache Memory
也就是CPU
高速緩存。相對于硬盤讀取速度來說內(nèi)存讀取的效率非常高音比,但是與 CPU
還是相差數(shù)量級俭尖,所以在 CPU 和主存間引入了多級緩存,目的是為了做一下緩沖洞翩。
CPU
內(nèi)部集成的緩存稱為一級緩存(L1 Cache
)目溉,外部的稱為二級緩存(L2 Cache
)。
一級緩存中又分為數(shù)據(jù)緩存(D-Cache
)和指令緩存(I-Cache
)菱农。二者可以同時被CPU進(jìn)行訪問,減少了爭用Cache
所造成的沖突柿估,提高了CPU的效能循未。
CPU的一級緩存通常都是靜態(tài)RAM
(Static RAM/SRAM),速度非筹啵快的妖,但是貴
二級緩存
是CPU
性能表現(xiàn)的關(guān)鍵之一,在CPU核心不變化的情況下足陨,增加二級緩存容量能使性能大幅度提高嫂粟。而同一核心的CPU高低端之分往往也是在二級緩存上存在差異
三級緩存
是為讀取二級緩存后未命中的數(shù)據(jù)設(shè)計的一種緩存,在擁有三級緩存的CPU中墨缘,只有約5%的數(shù)據(jù)需要從內(nèi)存中調(diào)用星虹,這進(jìn)一步提高了CPU的效率零抬,從某種意義上說,預(yù)取效率的提高宽涌,大大降低了生產(chǎn)成本卻提供了非常接近理想狀態(tài)的性能
1.3 Main Memory
Main Memory
就是主存平夜,主存比 L1、L2
緩存要大很多
注意:部分高端機(jī)器還有 L3
三級緩存卸亮。
內(nèi)存中相關(guān)概念:
- ROM(Read Only Memory)
只讀儲存器 忽妒,對于電腦來講就是硬盤,在系統(tǒng)停止供電的時候仍然可以保持?jǐn)?shù)據(jù) - PROM
PROM
是可編程的ROM
兼贸,PROM
和EPROM
(可擦除可編程ROM)兩者區(qū)別是段直,PROM
是一次性的,也就是軟件灌入后溶诞,就無法修改了鸯檬,現(xiàn)在已經(jīng)不可能使用了,而EPROM
是通過紫外光的照射擦除原先的程序很澄,是一種通用的存儲器京闰。另外一種EEPROM
是通過電子擦除,價格很高甩苛,寫入時間很長蹂楣,寫入很慢。 - RAM(Random Access Memory)
隨機(jī)儲存器 讯蒲,就是電腦內(nèi)存條
痊土。用于存放動態(tài)數(shù)據(jù)。(也叫運行內(nèi)存)系統(tǒng)運行的時候墨林,需要把操作系統(tǒng)從ROM
中讀取出來赁酝,放在RAM
中運行,而RAM
通常都是在掉電之后就丟失數(shù)據(jù)旭等,典型的RAM
就是計算機(jī)的內(nèi)存 - 靜態(tài)RAM(Static RAM/SRAM)
當(dāng)數(shù)據(jù)被存入其中后不會消失酌呆。SRAM
速度非常快搔耕,是目前讀寫最快的存儲設(shè)備隙袁。當(dāng)這個SRAM
單元被賦予0 或者1 的狀態(tài)之后,它會保持這個狀態(tài)直到下次被賦予新的狀態(tài)或者斷電之后才會更改或者消失弃榨。需要4-6 只晶體管實現(xiàn)菩收, 價格昂貴。
一級,二級,三級緩存都是使用SRAM
- 動態(tài)RAM(Dynamic RAM/DRAM)
DRAM
必須在一定的時間內(nèi)不停的刷新才能保持其中存儲的數(shù)據(jù)鲸睛。DRAM
只要1 只晶體管就可以實現(xiàn)娜饵。
DRAM
保留數(shù)據(jù)的時間很短,速度也比SRAM
慢官辈,不過它還是比任何的ROM都要快箱舞,但從價格上來說DRAM
相比SRAM
要便宜很 多遍坟,
計算機(jī)內(nèi)存就是DRAM
的
1.4 主存存取原理
主存有兩個指標(biāo):尋址
(ns,納秒級別)褐缠,帶寬
(很大政鼠,指單位時間內(nèi)字節(jié)流大小)队魏,在尋址上磁盤比內(nèi)存慢了十萬倍
目前計算機(jī)使用的主存基本都是隨機(jī)讀寫存儲器(RAM)公般,現(xiàn)代RAM的結(jié)構(gòu)和存取原理比較復(fù)雜,這里本文拋卻具體差別胡桨,抽象出一個十分簡單的存取模型來說明RAM的工作原理官帘。
從抽象角度看,主存是一系列的存儲單元組成的矩陣昧谊,每個存儲單元存儲固定大小的數(shù)據(jù)刽虹。每個存儲單元有唯一的地址,現(xiàn)代主存的編址規(guī)則比較復(fù)雜呢诬,這里將其簡化成一個二維地址:通過一個行地址和一個列地址可以唯一定位到一個存儲單元涌哲。上圖展示了一個4 x 4的主存模型。
主存的存取過程如下:
- 當(dāng)系統(tǒng)需要讀取主存時尚镰,則將地址信號放到地址總線上傳給主存阀圾,主存讀到地址信號后,解析信號并定位到指定存儲單元狗唉,然后將此存儲單元數(shù)據(jù)放到數(shù)據(jù)總線上初烘,供其它部件讀取。
- 寫主存的過程類似分俯,系統(tǒng)將要寫入單元地址和數(shù)據(jù)分別放在地址總線和數(shù)據(jù)總線上肾筐,主存讀取兩個總線的內(nèi)容,做相應(yīng)的寫操作缸剪。
這里可以看出吗铐,主存存取的時間僅與存取次數(shù)呈線性關(guān)系,因為不存在機(jī)械操作杏节,兩次存取的數(shù)據(jù)的“距離”不會對時間有任何影響,例如拢锹,先取A0再取A1和先取A0再取D3的時間消耗是一樣的。
1.5 磁盤存取原理
在磁盤的維度里有兩個指標(biāo):尋址
(m/s:每秒幾M)他巨、帶寬
(G/M充坑,帶寬是G或者M(jìn)的减江,指單位時間內(nèi)字節(jié)流大小)
與主存不同捻爷,磁盤I/O存在機(jī)械運動耗費辈灼,因此磁盤I/O的時間消耗是巨大的。
下圖是磁盤的整體結(jié)構(gòu)示意圖也榄。
一個磁盤由大小相同且同軸的圓形盤片組成巡莹,磁盤可以轉(zhuǎn)動(各個磁盤必須同步轉(zhuǎn)動)。在磁盤的一側(cè)有磁頭支架甜紫,磁頭支架固定了一組磁頭降宅,每個磁頭負(fù)責(zé)存取一個磁盤的內(nèi)容。磁頭不能轉(zhuǎn)動囚霸,但是可以沿磁盤半徑方向運動(實際是斜切向運動)腰根,每個磁頭同一時刻也必須是同軸的,即從正上方向下看拓型,所有磁頭任何時候都是重疊的(不過目前已經(jīng)有多磁頭獨立技術(shù)额嘿,可不受此限制)。
下圖是磁盤結(jié)構(gòu)的示意圖劣挫。
盤片被劃分成一系列同心環(huán)册养,圓心是盤片中心,每個同心環(huán)叫做一個磁道揣云,所有半徑相同的磁道組成一個柱面捕儒。磁道被沿半徑線劃分成一個個小的段,每個段叫做一個扇區(qū)邓夕,每個扇區(qū)是磁盤的最小存儲單元刘莹。為了簡單起見,我們下面假設(shè)磁盤只有一個盤片和一個磁頭焚刚。
當(dāng)需要從磁盤讀取數(shù)據(jù)時点弯,系統(tǒng)會將數(shù)據(jù)邏輯地址傳給磁盤,磁盤的控制電路按照尋址邏輯將邏輯地址翻譯成物理地址矿咕,即確定要讀的數(shù)據(jù)在哪個磁道抢肛,哪個扇區(qū)。為了讀取這個扇區(qū)的數(shù)據(jù)碳柱,需要將磁頭放到這個扇區(qū)上方捡絮,為了實現(xiàn)這一點,磁頭需要移動對準(zhǔn)相應(yīng)磁道莲镣,這個過程叫做尋道
福稳,所耗費時間叫做尋道時間
,然后磁盤旋轉(zhuǎn)將目標(biāo)扇區(qū)旋轉(zhuǎn)到磁頭下瑞侮,這個過程耗費的時間叫做旋轉(zhuǎn)時間
的圆。
磁盤有磁道和扇區(qū)鼓拧,一扇區(qū) 512Byte
。如果一個區(qū)域足夠小越妈,帶來一個成本變大(索引)季俩。操作系統(tǒng),無論讀多少數(shù)據(jù)梅掠,都是最少 4k
磁盤中拿酌住,即:每個存儲塊稱為一頁
的大小
點擊了解 為什么MySQL數(shù)據(jù)頁是16K,系統(tǒng)CPU是4K
1.6 局部性原理與磁盤預(yù)讀
由于存儲介質(zhì)的特性瓤檐,磁盤本身存取就比主存慢很多赂韵,再加上機(jī)械運動耗費,磁盤的存取速度往往是主存的幾百分分之一挠蛉,因此為了提高效率祭示,要盡量減少磁盤I/O。為了達(dá)到這個目的谴古,磁盤往往不是嚴(yán)格按需讀取质涛,而是每次都會預(yù)讀,即使只需要一個字節(jié)掰担,磁盤也會從這個位置開始汇陆,順序向后讀取一定長度的數(shù)據(jù)放入內(nèi)存。
這樣做的理論依據(jù)是計算機(jī)科學(xué)中著名的局部性原理:
當(dāng)一個數(shù)據(jù)被用到時带饱,其附近的數(shù)據(jù)也通常會馬上被使用毡代。程序運行期間所需要的數(shù)據(jù)通常比較集中。由于磁盤順序讀取的效率很高(不需要尋道時間勺疼,只需很少的旋轉(zhuǎn)時間)教寂,因此對于具有局部性的程序來說,預(yù)讀可以提高I/O效率执庐。
預(yù)讀的長度一般為頁(page)
的整倍數(shù)酪耕。頁是計算機(jī)管理存儲器的邏輯塊,硬件及操作系統(tǒng)往往將主存和磁盤存儲區(qū)分割為連續(xù)的大小相等的塊轨淌,每個存儲塊稱為一頁(在許多操作系統(tǒng)中迂烁,頁的大小通常為4k
),主存和磁盤以頁為單位交換數(shù)據(jù)
递鹉。當(dāng)程序要讀取的數(shù)據(jù)不在主存中時盟步,會觸發(fā)一個缺頁異常,此時系統(tǒng)會向磁盤發(fā)出讀盤信號躏结,磁盤會找到數(shù)據(jù)的起始位置并向后連續(xù)讀取一頁或幾頁載入內(nèi)存中址芯,然后異常返回,程序繼續(xù)運行。
1.7 索引存儲位置
假如文件很大了谷炸,對應(yīng)得索引也會很大,以B+
樹索引為例解析索引和文件存儲位置:
數(shù)據(jù)
和索引
其實都是存儲在硬盤當(dāng)中的禀挫,然后這時候真正查的時候是要用到一個東西旬陡,就是在內(nèi)存
里邊準(zhǔn)備一個B+
樹,內(nèi)存是速度最快的地方语婴,所以在內(nèi)存里邊準(zhǔn)備了一個B+
樹描孟, B+
樹所有的葉子就是4k小格子。B+樹其實數(shù)干是在內(nèi)存里的
砰左,比如說的區(qū)間和偏移匿醒,然后這個時候如果用戶想查,只要查詢的時候缠导,注意索引在where
條件里廉羔,只要命中索引了,那么這個查詢在B+
樹會走樹干僻造,最終找到某一個葉子
比如身份證號憋他,剛好在葉子代表這個區(qū)間里,那么把它從磁盤讀到內(nèi)存髓削,把它解析完之后竹挡,最笨的方法,遍歷完了之后立膛,可以知道應(yīng)該下一次把哪個data page
放到內(nèi)存里邊讀進(jìn)來揪罕,那么就可以找到我們那筆記錄了。
由于需要從磁盤讀到內(nèi)存宝泵,如果把這些索引再堆到內(nèi)存里的話好啰,內(nèi)存不夠,存不下這些索引鲁猩,所以 索引和數(shù)據(jù)都放在磁盤章母,內(nèi)存里只存一個樹干怜姿,只存一些區(qū)間
。
這樣的話是充分利用了各自的能力,磁盤能存很多東西夺衍,然后內(nèi)存速度快
,然后用一種數(shù)據(jù)結(jié)構(gòu)可以加快遍歷的一個查找的速度榜聂,然后數(shù)據(jù)又是分而治之的存儲唉俗,所以這時候獲取數(shù)據(jù)速度極快,最終的目的就是為了什么娱仔?減少I/O的流量
2 內(nèi)存分頁
雖然Java語言的這些特點很容易“慣壞”開發(fā)人員沐飘,使得我們不需要太關(guān)心到底程序是怎么使用內(nèi)存的,使用了多少內(nèi)存。但是我們最好也了解Java
是如何管理內(nèi)存的耐朴,當(dāng)我們真的遇到OutOfMemoryError
時不會奇怪地問借卧,為什么Java也有內(nèi)存泄漏:要快速地知道到底什么地方導(dǎo)致了 OutOfMemoryError
,并能根據(jù)錯誤日志快速地定位出錯原因
2.1 物理內(nèi)存與虛擬內(nèi)存
2.1.1 物理內(nèi)存
所謂物理內(nèi)存就是我們通常所說的RAM
(隨機(jī)存儲器)筛峭。在計算機(jī)中铐刘,還有一個存儲單元叫寄存器
,它用于存儲計算單元執(zhí)行指令(如浮點影晓、整數(shù)等運算時)的中間結(jié)果镰吵。寄存器的大小決定了一次計算可使用的最大數(shù)值。
連接處理器和RAM
或者處理器和寄存器的是地址總線挂签,這個地址總線的寬度影響了物理地址的索引范圍疤祭,因為總線的寬度決定了處理器一次可以從寄存器或者內(nèi)存中獲取多少個bit
。同時也決定了處理器最大可以尋址的地址空間饵婆,如32位地址總線可以尋址的范圍為(0x0000 0000?0ffff ffff
勺馆。這個范圍是2^32=4294967296個內(nèi)存位置,每個地址會引用一個字節(jié)啦辐,所以32位
總線寬度可以有4GB
的內(nèi)存空間谓传。
通常情況下,地址總線
和寄存器
或者RAM
有相同的位數(shù)芹关,因為這樣更容易傳輸數(shù)據(jù)续挟,但是也有不一致的情況,如x86
的32位
寄存器寬度的物理地址可能有兩種大小侥衬,分別是32位
物理地址和36位
物理地址诗祸,擁有36位物理地址的是Pentium Pro和更高型號。
不管是在Windows
系統(tǒng)還是Linux
系統(tǒng)下轴总,我們要運行程序直颅,都要向操作系統(tǒng)先申請內(nèi)存地址。 通常操作系統(tǒng)管理內(nèi)存的申請空間是按照進(jìn)程來管理的怀樟,每個進(jìn)程擁有一段獨立的地址空間功偿,每個進(jìn)程之間不會相互重合,操作系統(tǒng)也會保證每個進(jìn)程只能訪問自己的內(nèi)存空間往堡。
這主要是從程序的安全性來考慮的械荷,也便于操作系統(tǒng)來管理物理內(nèi)存。
其實上面所說的進(jìn)程的內(nèi)存空間的獨立主要是指邏輯上獨立虑灰,也就是這個獨立是由操作系統(tǒng)來保證的吨瞎,但是真正的物理空間是不是只能由一個進(jìn)程來使用就不一定 了。因為隨著程序越來越龐大和設(shè)計的多任務(wù)性穆咐,物理內(nèi)存無法滿足程序的需求颤诀,在這種情況下就有了虛擬內(nèi)存的出現(xiàn)字旭。
2.1.2 虛擬內(nèi)存
虛擬內(nèi)存的出現(xiàn)使得多個進(jìn)程在同時運行時可以共享物理內(nèi)存,這里的共享只是空間上共享
崖叫,在邏輯上它們?nèi)匀皇遣荒芟嗷ピL問的遗淳。虛擬地址不但可以讓進(jìn)程共享物理內(nèi)存、提高內(nèi)存利用率心傀,而且還能夠擴(kuò)展內(nèi)存的地址空間洲脂,如一個虛擬地址可能被映射到一段物理內(nèi)存、文件或者其他可以尋址的存儲上剧包。
一個進(jìn)程在不活動的情況下,操作系統(tǒng)將這個物理內(nèi)存中的數(shù)據(jù)移到一個磁盤文件中(也就是通常windows
系統(tǒng)上的頁面文件往果,或者Linux
系統(tǒng)上的SWAP
交換分區(qū))疆液,而真正高效的物理內(nèi)存留給正在活動的程序使用。在這種情況下陕贮,在我們重新喚醒一個很長時間沒有使用的程序時堕油,磁盤會吱吱作響,并且會有一個短暫的停頓得到印證肮之,這時操作系統(tǒng)又會把磁盤上的數(shù)據(jù)重新交互到物理內(nèi)存中掉缺。但是我們必須要避免這種情況的經(jīng)常出現(xiàn),如果操作系統(tǒng)頻繁地交互物理內(nèi)存的數(shù)據(jù)和磁盤數(shù)據(jù)戈擒,則效率將會非常低眶明,尤其是在Linux服務(wù)器上,我們要關(guān)注Linux中swap的分區(qū)的活躍度搜囱。
如果swap分區(qū)被頻繁使用,系統(tǒng)將會非常緩慢柑土,很可能意味著物理內(nèi)存已經(jīng)嚴(yán)重不足或者某些程序沒有及時釋放內(nèi)存蜀肘。
在Linux
分區(qū)中SWAP
意思是交換,顧名思義稽屏,當(dāng)某進(jìn)程向OS
請求內(nèi)存發(fā)現(xiàn)不足時扮宠,OS
會把內(nèi)存中暫時不用的數(shù)據(jù)交換出去,放在SWAP
分區(qū)中狐榔,這個過程稱為SWAP OUT
坛增。當(dāng)某進(jìn)程又需要這些數(shù)據(jù)且OS
發(fā)現(xiàn)還有空閑物理內(nèi)存時,又會把SWAP
分區(qū)中的數(shù)據(jù)交換回物理內(nèi)存中荒叼,這個過程稱為SWAP IN
2.2 內(nèi)存分頁大小對性能提升原理
首先轿偎,我們需要回顧一小部分計算機(jī)組成原理,這對理解大內(nèi)存分頁至于JVM
性能的提升是有好處的被廓。
2.2.1 什么是內(nèi)存分頁
我們知道坏晦,CPU
是通過尋址來訪問內(nèi)存的。32
位CPU
的尋址寬度是 0~0xFFFFFFFF
,計算后得到的大小是4G
昆婿,也就是說可支持的物理內(nèi)存最大是4G
球碉。但在實踐過程中,碰到了這樣的問題仓蛆,程序需要使用4G內(nèi)存睁冬,而可用物理內(nèi)存小于4G,導(dǎo)致程序不得不降低內(nèi)存占用看疙。
為了解決此類問題豆拨,現(xiàn)代CPU
引入了 MMU
(Memory Management Unit
內(nèi)存管理單元)
MMU
的核心思想是利用虛擬地址替代物理地址,即CPU
尋址時使用虛址能庆,由MMU
負(fù)責(zé)將虛址映射為物理地址施禾。MMU
的引入,解決了對物理內(nèi)存的限制搁胆,對程序來說弥搞,就像自己在使用4G
內(nèi)存一樣。
內(nèi)存分頁(Paging
)是在使用MMU
的基礎(chǔ)上渠旁,提出的一種內(nèi)存管理機(jī)制攀例。它將虛擬地址
和物理地址
按固定大小(4K
)分割成頁(page
)和頁幀(page frame
)顾腊,并保證 頁與頁幀的大小相同
粤铭,這種機(jī)制,從數(shù)據(jù)結(jié)構(gòu)上投慈,保證了訪問內(nèi)存的高效承耿,并使OS
能支持非連續(xù)性的內(nèi)存分配。在程序內(nèi)存不夠用時伪煤,還可以將不常用的物理內(nèi)存頁轉(zhuǎn)移到其他存儲設(shè)備上加袋,比如磁盤,這就是大家耳熟能詳?shù)奶摂M內(nèi)存抱既。
頁表其實是一個數(shù)組用于把虛擬頁號
和物理幀號
對應(yīng)起來
其索引為VPN
(虛擬地址) 索引值對應(yīng)的項為PTE
(頁表項) 項中的值為PFN
(物理頁幀)职烧,每個PTE
中還有很多別的內(nèi)容,比如有很多不同的位:有效位防泵、保護(hù)位蚀之、存在位、臟位捷泞、參考位
虛擬地址
與物理地址
需要通過映射足删,才能使CPU
正常工作。而映射就需要存儲映射表
锁右。在現(xiàn)代CPU
架構(gòu)中失受,映射關(guān)系通常被存儲在物理內(nèi)存上一個被稱之為頁表(page table)
的地方讶泰。
如下圖:
從這張圖中,可以清晰地看到CPU
與頁表拂到,物理內(nèi)存之間的交互關(guān)系痪署。
由于頁表是被存儲在內(nèi)存中的。我們知道CPU
通過總線訪問內(nèi)存兄旬,肯定慢于直接訪問寄存器的狼犯。為了進(jìn)一步優(yōu)化性能,現(xiàn)代CPU
架構(gòu)引入了TLB
(Translation lookaside buffer
领铐,頁表寄存器緩沖
)悯森,用來緩存一部分經(jīng)常訪問的頁表內(nèi)容。
如下圖:
2.2.2 為什么要支持大內(nèi)存分頁
TLB
是有限的绪撵,這點毫無疑問呐馆。當(dāng)超出TLB
的存儲極限時,就會發(fā)生 TLB miss
莲兢,之后,OS
就會命令CPU
去訪問內(nèi)存上的頁表续膳。如果頻繁的出現(xiàn)TLB miss
改艇,程序的性能會下降地很快。
為了讓TLB
可以存儲更多的頁地址映射關(guān)系坟岔,我們的做法是調(diào)大內(nèi)存分頁大小谒兄。
如果一個頁4M
,對比一個頁4K社付,前者可以讓TLB多存儲1000個頁地址映射關(guān)系承疲,性能的提升是比較可觀的。
2.3 調(diào)整OS和JVM內(nèi)存分頁
在Linux
和windows
下要啟用大內(nèi)存頁鸥咖,有一些限制和設(shè)置步驟燕鸽。
2.3.1 Linux
Linux限制:需要2.6內(nèi)核以上或2.4內(nèi)核已打大內(nèi)存頁補(bǔ)丁。
確認(rèn)是否支持啼辣,請在終端敲如下命令:
# cat /proc/meminfo | grep Huge
HugePages_Total: 0
HugePages_Free: 0
Hugepagesize: 2048 kB
如果有HugePage
字樣的輸出內(nèi)容啊研,說明OS
是支持大內(nèi)存分頁的。Hugepagesize
就是默認(rèn)的大內(nèi)存頁size
接下來鸥拧,為了讓JVM
可以調(diào)整大內(nèi)存頁size
党远,需要設(shè)置下OS
共享內(nèi)存段最大值和大內(nèi)存頁數(shù)量。
2.3.1.1 共享內(nèi)存段最大值
建議這個值大于Java Heap size
富弦,這個例子里設(shè)置了4G內(nèi)存沟娱。
# echo 4294967295 > /proc/sys/kernel/shmmax
2.3.1.2 大內(nèi)存頁數(shù)量
# echo 154 > /proc/sys/vm/nr_hugepages
這個值一般是 Java
進(jìn)程占用最大內(nèi)存/單個頁的大小 ,比如java設(shè)置 1.5G腕柜,單個頁 10M济似,那么數(shù)量為 1536/10 = 154矫废。
注意
:因為proc
是內(nèi)存FS
,為了不讓設(shè)置在重啟后被沖掉碱屁,建議寫個腳本放到 init 階段(rc.local)磷脯。
2.3.2 Windows
Windows限制:僅支持 windows server 2003 以上server版本
操作步驟:
- Control Panel -> Administrative Tools -> Local Security Policy
- Local Policies -> User Rights Assignment
- 雙擊
Lock pages in memory
, 添加用戶和組 - 重啟電腦
注意: 需要管理員操作。
2.3.3 單個頁大小調(diào)整
JVM
啟用時加參數(shù) -XX:LargePageSizeInBytes=10m
如果JDK是在1.5 update5以前的娩脾,還需要手動加 -XX:+UseLargePages
赵誓,作用是啟用大內(nèi)存頁支持。
2.4 大內(nèi)存分頁的副作用
因為每頁size
變大了柿赊,導(dǎo)致JVM
在計算Heap
內(nèi)部分區(qū)(perm, new, old)內(nèi)存占用比例時俩功,會出現(xiàn)超出正常值的劃分。最壞情況下是碰声,某個區(qū)會多占用一個頁的大小诡蜓。不過后續(xù)jvm版本也在調(diào)整這個策略。
一般情況胰挑,不建議將頁size
調(diào)得太大蔓罚,4-64M
,是可以接受的(默認(rèn)是4M)
2.5 Fork
2.5.1 fork創(chuàng)建子進(jìn)程特點
-
父子進(jìn)程
:fork
調(diào)用后瞻颂,會創(chuàng)建一個新的子進(jìn)程豺谈,該子進(jìn)程與父進(jìn)程幾乎完全相同,包括代碼贡这、數(shù)據(jù)和打開文件等茬末。子進(jìn)程從fork
調(diào)用的位置開始執(zhí)行,父進(jìn)程和子進(jìn)程在fork
調(diào)用之后的代碼處繼續(xù)執(zhí)行盖矫。 -
資源繼承
:子進(jìn)程繼承了父進(jìn)程的大部分資源丽惭,包括打開的文件、文件描述符辈双、信號處理器等责掏。但是有些資源(如互斥鎖和定時器)可能需要進(jìn)行特殊處理,以避免競爭條件或資源泄漏湃望。 -
內(nèi)存
:父進(jìn)程和子進(jìn)程擁有獨立的虛擬內(nèi)存空間拷橘,每個進(jìn)程都有自己的內(nèi)存映射表。子進(jìn)程通過寫時復(fù)制(copy-on-write
)機(jī)制與父進(jìn)程共享物理內(nèi)存喜爷,只有在需要修改內(nèi)存內(nèi)容時才會進(jìn)行復(fù)制冗疮。 - 父子關(guān)系:父進(jìn)程可以通過
fork
的返回值判斷是否為子進(jìn)程。父進(jìn)程的fork
返回子進(jìn)程的PID
檩帐,而子進(jìn)程的fork返回0术幔。這樣可以根據(jù)返回值的不同,在父子進(jìn)程中執(zhí)行不同的邏輯湃密。
2.5.2 Copy On Write
在創(chuàng)建子進(jìn)程的過程中诅挑,操作系統(tǒng)會把父進(jìn)程的頁表
復(fù)制一份給子進(jìn)程四敞,這個頁表記錄著虛擬地址
和物理地址
映射關(guān)系,而不會復(fù)制物理內(nèi)存拔妥,也就是說忿危,兩者的虛擬空間不同,但其對應(yīng)的物理空間是同一個没龙。
這樣一來铺厨,子進(jìn)程
就共享了父進(jìn)程的物理內(nèi)存數(shù)據(jù)了,這樣能夠節(jié)約物理內(nèi)存資源硬纤,頁表對應(yīng)的頁表項的屬性會標(biāo)記該物理內(nèi)存的權(quán)限為只讀解滓。
當(dāng)父進(jìn)程或者子進(jìn)程在向共享內(nèi)存發(fā)起寫操作時,CPU
就會觸發(fā)寫保護(hù)中斷筝家,這個寫保護(hù)中斷
是由于違反權(quán)限導(dǎo)致的洼裤,然后操作系統(tǒng)會在寫保護(hù)中斷處理函數(shù)
里進(jìn)行物理內(nèi)存的復(fù)制,并重新設(shè)置其內(nèi)存映射關(guān)系溪王,將父子進(jìn)程的內(nèi)存讀寫權(quán)限設(shè)置為可讀寫腮鞍,最后才會對內(nèi)存進(jìn)行寫操作,這個過程被稱為寫時復(fù)制(Copy On Write)
莹菱。
寫時復(fù)制顧名思義缕减,在發(fā)生寫操作的時候,操作系統(tǒng)才會去復(fù)制物理內(nèi)存芒珠,這樣是為了防止 fork
創(chuàng)建子進(jìn)程時,由于物理內(nèi)存數(shù)據(jù)的復(fù)制時間過長而導(dǎo)致父進(jìn)程長時間阻塞的問題搅裙。
3 內(nèi)核空間與用戶空間
3.1 定義
一個計算機(jī)通常有一定大小的內(nèi)存空間皱卓,如使用的計算機(jī)是4GB
的地址空間,但是程序并不能完全使用這些地址空間部逮,因為這些地址空間被劃分為內(nèi)核空間
和用戶空間
娜汁。程序只能使用用戶空間的內(nèi)存,這里所說的使用是 指程序能夠申請的內(nèi)存空間
兄朋,并不是程序真正訪問的地址空間掐禁。
內(nèi)核空間
主要是指操作系統(tǒng)運行時所使用的用于程序調(diào)度、虛擬內(nèi)存的使用或者連接硬件資源等的程序邏輯颅和。
-
用戶空間(User Mode)
:是指應(yīng)用程序
運行時的執(zhí)行環(huán)境
傅事。在用戶態(tài)下,應(yīng)用程序只能訪問受限資源峡扩,如應(yīng)用程序自身的內(nèi)存空間蹭越、CPU
寄存器等,并且不能直接訪問操作系統(tǒng)的底層資源和硬件設(shè)備教届。
非內(nèi)核應(yīng)用程序運行在用戶空間钞翔,用戶空間中的代碼運行在較低的特權(quán)級別上 -
內(nèi)核空間(Kernel Mode)
:是指操作系統(tǒng)內(nèi)核
運行時的執(zhí)行環(huán)境
丹拯。在內(nèi)核態(tài)下健霹,操作系統(tǒng)具有更高的權(quán)限,可以直接訪問系統(tǒng)的硬件和底層資源粪糙,如 CPU、內(nèi)存忿项、設(shè)備驅(qū)動程序等蓉冈。
操作系統(tǒng)的核心,是操作系統(tǒng)工作的基礎(chǔ)倦卖,它負(fù)責(zé)管理系統(tǒng)的進(jìn)程洒擦、內(nèi)存、設(shè)備驅(qū)動程序怕膛、文件和網(wǎng)絡(luò)系統(tǒng)熟嫩,決定著系統(tǒng)的性能和穩(wěn)定性
3.2 為何需要內(nèi)核空間和用戶空間的劃分
由于每個進(jìn)程都獨立使用屬于自己的內(nèi)存一樣,為了保證操作系統(tǒng)的穩(wěn)定性褐捻,運行在操作系統(tǒng)中的 用戶程序不能訪問操作系統(tǒng)所使用的內(nèi)存空間
掸茅。這也是從安全性上考慮的,如訪問硬件資源只能由操作系統(tǒng)來發(fā)起柠逞,用戶程序不允許直接訪問硬件資源昧狮。如果用戶程序需要訪問硬件資源,如網(wǎng)絡(luò)連接等板壮,.可以調(diào)用操作系統(tǒng)提供的接口來實現(xiàn)逗鸣,這個調(diào)用接口的過程也就是系統(tǒng)調(diào)用。
每一次系統(tǒng)調(diào)用都會存在兩個內(nèi)存空間的切換绰精,通常的網(wǎng)絡(luò)傳輸也是一次系統(tǒng)調(diào)用撒璧,通過網(wǎng)絡(luò)傳輸?shù)臄?shù)據(jù)先是從內(nèi)核空間接收到遠(yuǎn)程主機(jī)的數(shù)據(jù),然后再從內(nèi)核空間復(fù)制到用戶空間笨使,供用戶程序使用卿樱。這種從內(nèi)核空間到用戶空間的數(shù)據(jù)復(fù)制很費時,雖然保住了程序運行的安全性和穩(wěn)定性硫椰,但是也犧牲了一部分效率繁调。但是現(xiàn)在已經(jīng)出現(xiàn)了很多其他技術(shù)能夠減少這種從內(nèi)核空間到用戶空間的數(shù)據(jù)復(fù)制的方式,如Linux系統(tǒng)提供了 sendflle文件傳輸方式靶草。
內(nèi)核空間和用戶空間的大小如何分配也是一個問題蹄胰,是更多地分配給用戶空間供用戶程序使用,還是首先保住內(nèi)核有足夠的空間來運行奕翔,這要平衡一下烤送。如果是一臺登錄服務(wù)器,很顯然糠悯,要分配更多的內(nèi)核空間帮坚,因為每一個登錄用戶操作系統(tǒng)都會初始化一個用戶進(jìn)程妻往,這個進(jìn)程大部分都在內(nèi)核空間里運行。在當(dāng)前的 Windows 32
位操作系統(tǒng)中默認(rèn)內(nèi)核空間和用戶空間的比例是1:1
(2GB的內(nèi)核空間试和,2GB的用戶空間)讯泣,而在32位Linux
系統(tǒng)中默認(rèn)的比例是1:3
(1GB的內(nèi)核空間,3GB的用戶空間)
3.3 內(nèi)核用戶空間切換的影響
java
的線程是映射到操作系統(tǒng)原生線程之上的阅悍,如果要阻塞或喚醒一個線程就需要操作系統(tǒng)介入好渠,需要在用戶態(tài)
與核心態(tài)
之間切換,這種切換會消耗大量的系統(tǒng)資源节视,因為用戶態(tài)
與內(nèi)核態(tài)
都有各自專用的內(nèi)存空間拳锚,專用的寄存器等,用戶態(tài)
切換至內(nèi)核態(tài)
需要傳遞給許多變量寻行、參數(shù)給內(nèi)核霍掺,內(nèi)核也需要保護(hù)好用戶態(tài)在切換時的一些寄存器值、變量等拌蜘,以便內(nèi)核態(tài)調(diào)用結(jié)束后切換回用戶態(tài)繼續(xù)工作杆烁。
如果線程狀態(tài)切換是一個高頻操作時,這將會消耗很多CPU處理時間
3.4 單核多核cpu與多線程
3.4.1 單核CPU為何也支持多線程呢
多任務(wù)系統(tǒng)往往需要同時執(zhí)行多道作業(yè)简卧。作業(yè)數(shù)往往大于機(jī)器的CPU
數(shù)兔魂,然而一顆CPU
同時只能執(zhí)行一項任務(wù),如何讓用戶感覺這些任務(wù)正在同時進(jìn)行呢? 操作系統(tǒng)的設(shè)計者巧妙地利用了時間片輪轉(zhuǎn)
的方式
時間片是CPU
分配給各個任務(wù)(線程)的時間
線程上下文
是指某一時間點CPU寄存器
和程序計數(shù)器(PC寄存器)
的內(nèi)容举娩,CPU
通過時間片分配算法來循環(huán)執(zhí)行任務(wù)(線程)析校,因為時間片非常短,所以CPU
通過不停地切換線程執(zhí)行铜涉。
換言之智玻,單CPU
這么頻繁,多核CPU
一定程度上可以減少上下文切換
3.4.2 超線程
現(xiàn)代CPU
除了處理器核心之外還包括寄存器骄噪、L1L2緩存這些存儲設(shè)備、浮點運算單元蠢箩、整數(shù)運算單元等一些輔助運算設(shè)備以及內(nèi)部總線等链蕊。一個多核的CPU
也就是一個CPU
上有多個處理器核心,就意味著程序的不同線程需要經(jīng)常在CPU
之間的外部總線上通信谬泌,同時還要處理不同CPU
之間不同緩存導(dǎo)致數(shù)據(jù)不一致的問題滔韵。
超線程
這個概念是Intel提出的,簡單來說是在一個CPU
上真正的并發(fā)兩個線程掌实,由于CPU
都是分時的(如果兩個線程A和B陪蜻,A正在使用處理器核心,B正在使用緩存或者其他設(shè)備贱鼻,那AB兩個線程就可以并發(fā)執(zhí)行宴卖,但是如果AB都在訪問同一個設(shè)備滋将,那就只能等前一個線程執(zhí)行完后一個線程才能執(zhí)行
)。實現(xiàn)這種并發(fā)的原理是 在CPU
里加了一個協(xié)調(diào)輔助核心症昏,根據(jù)Intel提供的數(shù)據(jù)随闽,這樣一個設(shè)備會使得設(shè)備面積增大5%,但是性能提高15%~30%
3.4.3 線程上下文切換
線程上下文
:指某一時間點CPU寄存器
和程序計數(shù)器(PC寄存器)
的內(nèi)容
線程上下文切換:
- 線程切換肝谭,同一進(jìn)程中的兩個線程之間的切換
- 進(jìn)程切換掘宪,兩個進(jìn)程之間的切換
- 模式切換,在給定線程中攘烛,用戶模式和內(nèi)核模式的切換
- 地址空間切換魏滚,將虛擬內(nèi)存切換到物理內(nèi)存
CPU
切換前把當(dāng)前任務(wù)的狀態(tài)保存下來,以便下次切換回這個任務(wù)時可以再次加載這個任務(wù)的狀態(tài)坟漱,然后加載下一任務(wù)的狀態(tài)并執(zhí)行鼠次。任務(wù)的狀態(tài)保存及再加載, 這段過程就叫做上下文切換
。
每個線程都有一個程序計數(shù)器(記錄要執(zhí)行的下一條指令)靖秩,一組寄存器(保存當(dāng)前線程的工作變量)须眷,堆棧(記錄執(zhí)行歷史,其中每一幀保存了一個已經(jīng)調(diào)用但未返回的過程)沟突。
程序計數(shù)器
是一個專用的寄存器花颗,用于表明指令序列中 CPU 正在執(zhí)行的位置,存的值為正在執(zhí)行的指令的位置或者下一個將要被執(zhí)行的指令的位置惠拭。
- 掛起當(dāng)前任務(wù)(線程/進(jìn)程)扩劝,將這個任務(wù)在 CPU 中的狀態(tài)(上下文)存儲于內(nèi)存中的某處
- 恢復(fù)一個任務(wù)(線程/進(jìn)程),在內(nèi)存中檢索下一個任務(wù)的上下文并將其在 CPU 的寄存器中恢復(fù)
-
跳轉(zhuǎn)到程序計數(shù)器所指向的位置(即跳轉(zhuǎn)到任務(wù)被中斷時的代碼行)职辅,以恢復(fù)該進(jìn)程在程序中]
image.png
問題
:線程運行過程中申請到的東西在切換時是否全部要保存棒呛,比如線程中有個循環(huán),或者聲明了很多對象域携,這些是否都要保存簇秒,也存在線程私有區(qū)嗎
在線程切換時,操作系統(tǒng)會保存線程的上下文信息秀鞭,包括線程的程序計數(shù)器趋观、寄存器值、堆棧指針等锋边。這些信息可以用來恢復(fù)線程的執(zhí)行狀態(tài)皱坛。
對于線程中的循環(huán)或聲明的對象,它們的狀態(tài)在線程切換時不會自動保存豆巨。線程中的循環(huán)會根據(jù)程序計數(shù)器的值來確定下一條要執(zhí)行的指令剩辟,而聲明的對象會存在線程的堆棧中
。當(dāng)線程切換時,這些狀態(tài)不會被保存贩猎,而是由新的線程重新執(zhí)行熊户。
然而,每個線程都有自己的線程棧融欧,用于保存局部變量和函數(shù)調(diào)用的信息敏弃。這個線程棧是線程私有的,不會被其他線程訪問到噪馏。因此麦到,線程中的局部變量和函數(shù)調(diào)用信息是在線程切換時自動保存的,無需額外的操作欠肾。
需要注意的是瓶颠,如果多個線程并發(fā)訪問共享資源,比如全局變量或共享對象刺桃,那么在切換時可能需要通過同步機(jī)制來保證數(shù)據(jù)的一致性粹淋。否則,可能會導(dǎo)致數(shù)據(jù)競爭和不確定的結(jié)果瑟慈。
3.4.4 線程上下文切換的影響
線程上下文
切換會導(dǎo)致額外的開銷桃移,常常表現(xiàn)為高并發(fā)執(zhí)行時速度會慢串行,因此減少上下文切換次數(shù)便可以提高多線程程序的運行效率葛碧。
-
直接消耗
:指的是CPU
寄存器需要保存和加載, 系統(tǒng)調(diào)度器的代碼需要執(zhí)行, TLB實例需要重新加載, CPU 的pipeline需要刷掉 -
間接消耗
:指的是多核的cache之間得共享數(shù)據(jù), 間接消耗對于程序的影響要看線程工作區(qū)操作數(shù)據(jù)的大小
3.4.5 引起線程上下文切換的因素
引起線程上下文切換的因素:
- 當(dāng)前執(zhí)行任務(wù)(線程)的時間片用完之后借杰,系統(tǒng)
CPU
正常調(diào)度下一個任務(wù) - 中斷處理,在中斷處理中进泼,其他程序
打斷
了當(dāng)前正在運行的程序蔗衡。當(dāng)CPU接收到中斷請求時,會把正在運行的程序和發(fā)起中斷請求的程序之間進(jìn)行一次上下文切換乳绕。中斷分為硬件中斷
和軟件中斷
绞惦,軟件中斷包括因為IO阻塞、未搶到資源或者用戶代碼等原因洋措,線程被掛起济蝉。 - 用戶態(tài)切換,對于一些操作系統(tǒng)菠发,當(dāng)進(jìn)行用戶態(tài)切換時也會進(jìn)行一次上下文切換王滤,雖然這不是必須的。
- 多個任務(wù)搶占鎖資源雷酪,在多任務(wù)處理中淑仆,
CPU
會在不同程序之間來回切換涝婉,每個程序都有相應(yīng)的處理時間片哥力,CPU在兩個時間片的間隔中進(jìn)行上下文切換
因此優(yōu)化手段有:
- 無鎖并發(fā)編程,多線程處理數(shù)據(jù)時,可以用一些辦法來避免使用鎖吩跋,如將數(shù)據(jù)的ID按照Hash取模分段寞射,不同的線程處理不同段的數(shù)據(jù)
-
CAS
算法,Java的Atomic包使用CAS算法來更新數(shù)據(jù)锌钮,而不需要加鎖
使用最少線程 - 協(xié)程桥温,單線程里實現(xiàn)多任務(wù)的調(diào)度,并在單線程里維持多個任務(wù)間的切換
合理設(shè)置線程數(shù)目既可以最大化利用CPU梁丘,又可以減少線程切換的開銷侵浸。
- 高并發(fā),低耗時的情況氛谜,建議少線程掏觉。
- 低并發(fā),高耗時的情況:建議多線程值漫。
- 高并發(fā)高耗時澳腹,要分析任務(wù)類型、增加排隊杨何、加大線程數(shù)
3.4.6 切換查看
Linux
系統(tǒng)下可以使用vmstat
命令來查看上下文切換的次數(shù)酱塔, 其中cs
列就是指上下文切換的數(shù)目(一般情況下, 空閑系統(tǒng)的上下文切換每秒大概在1500以下)
3.4.7 Java線程調(diào)度
Java線程調(diào)度:
-
搶占式調(diào)度
指的是每條線程執(zhí)行的時間、線程的切換都由系統(tǒng)控制危虱,系統(tǒng)控制指的是在系統(tǒng)某種運行機(jī)制下羊娃,可能每條線程都分同樣的執(zhí)行時間片,也可能是某些線程執(zhí)行的時間片較長槽地,甚至某些線程得不到執(zhí)行的時間片迁沫。在這種機(jī)制下,一個線程的堵塞不會導(dǎo)致整個進(jìn)程堵塞捌蚊。
java
使用的線程調(diào)度使用搶占式調(diào)度集畅,Java
中線程會按優(yōu)先級分配CPU
時間片運行,且優(yōu)先級越高越優(yōu)先執(zhí)行缅糟,但優(yōu)先級高并不代表能獨自占用執(zhí)行時間片挺智,可能是優(yōu)先級高得到越多的執(zhí)行時間片,反之窗宦,優(yōu)先級低的分到的執(zhí)行時間少但不會分配不到執(zhí)行時間赦颇。 -
協(xié)同式調(diào)度
指某一線程執(zhí)行完后主動通知系統(tǒng)切換到另一線程上執(zhí)行,這種模式就像接力賽一樣赴涵,一個人跑完自己的路程就把接力棒交接給下一個人媒怯,下個人繼續(xù)往下跑。線程的執(zhí)行時間由線程本身控制髓窜,線程切換可以預(yù)知扇苞,不存在多線程同步問題欺殿,但它有一個致命弱點:如果一個線程編寫有問題,運行到一半就一直堵塞鳖敷,那么可能導(dǎo)致整個系統(tǒng)崩潰脖苏。
3.4.8 進(jìn)程切換和線程切換
進(jìn)程切換和線程切換區(qū)別:
-
進(jìn)程切換
:進(jìn)程切換涉及到更多的內(nèi)容,包括整個進(jìn)程的地址空間定踱、全局變量棍潘、文件描述符等。因此崖媚,進(jìn)程切換的開銷通常比線程切換大亦歉。 -
線程切換
:線程切換只涉及到線程的堆棧、寄存器和程序計數(shù)器等畅哑,不涉及進(jìn)程級別的資源鳍徽,因此線程切換的開銷較小。
3.4.9 為什么并發(fā)執(zhí)行線程要加鎖
并發(fā)執(zhí)行線程
需要加鎖主要是為了保護(hù)共享數(shù)據(jù)敢课,防止出現(xiàn)競態(tài)條件
阶祭。
競態(tài)條件
是指當(dāng)多個線程同時訪問和操作同一塊數(shù)據(jù)時,最終結(jié)果依賴于線程的執(zhí)行順序直秆,這可能導(dǎo)致數(shù)據(jù)的不一致性濒募。
通過加鎖,我們可以確保在任何時刻只有一個線程能夠訪問共享數(shù)據(jù)圾结,從而避免競態(tài)條件
瑰剃,確保數(shù)據(jù)的一致性和完整性。
3.5 Windows和Linux的CPU競爭方式
CPU
競爭(CPU contention
)是指多個進(jìn)程
或線程
在同一時間競爭使用有限的CPU
資源筝野。在多任務(wù)操作系統(tǒng)中晌姚,CPU
競爭是很常見的現(xiàn)象。操作系統(tǒng)的任務(wù)調(diào)度器負(fù)責(zé)管理這些競爭歇竟,確保所有進(jìn)程和線程都能得到合理的CPU
時間挥唠。Windows
和Linux
作為兩種不同的操作系統(tǒng),它們在處理CPU競爭方面有一些區(qū)別:
-
調(diào)度算法
:
Windows
和Linux
使用不同的任務(wù)調(diào)度算法焕议。Windows
使用優(yōu)先級驅(qū)動的搶占式
多任務(wù)調(diào)度器宝磨,它根據(jù)進(jìn)程的優(yōu)先級
來分配CPU
時間。
Linux
使用完全公平
調(diào)度器(CFS
)盅安,它根據(jù)進(jìn)程的虛擬運行時間來分配CPU時間唤锉,以實現(xiàn)公平的資源分配
。 -
優(yōu)先級
:Windows
和Linux
的進(jìn)程優(yōu)先級有所不同别瞭。Windows
有0-31
個優(yōu)先級級別窿祥,其中0-15
為動態(tài)優(yōu)先級
,16-31
為實時優(yōu)先級
蝙寨。Linux
有-20
到19
的優(yōu)先級范圍晒衩,其中-20
表示最高優(yōu)先級
号胚,19
表示最低優(yōu)先級
。這些優(yōu)先級值在兩個系統(tǒng)中的含義和作用也有所不同浸遗。 -
實時調(diào)度
:Windows
和Linux
都支持實時調(diào)度,但實現(xiàn)方式不同箱亿。
Windows
使用實時
優(yōu)先級(16-31
)來支持實時任務(wù)跛锌,這些任務(wù)具有比普通任務(wù)更高的優(yōu)先級。
Linux
使用SCHED_FIFO
和SCHED_RR
兩種實時調(diào)度策略届惋,它們分別對應(yīng)先進(jìn)先出和輪詢調(diào)度算法髓帽。 -
多處理器支持
:Windows
和Linux
都支持多處理器系統(tǒng),但在處理器親和性和負(fù)載均衡方面有所不同脑豹。
Windows
使用處理器親和性掩碼來指定進(jìn)程可以在哪些處理器上運行郑藏,而Linux
使用cpuset
來實現(xiàn)類似的功能。在負(fù)載均衡方面瘩欺,Windows
和Linux
都有各自的策略和算法必盖。 -
用戶界面
:Windows
和Linux
在用戶界面方面也有所不同。
Windows
提供了圖形化的任務(wù)管理器俱饿,用戶可以通過這個工具查看和管理系統(tǒng)中的進(jìn)程和資源使用情況歌粥。Linux
通常使用命令行工具,如top
和htop
拍埠,來查看和管理進(jìn)程失驶,但也有圖形化的系統(tǒng)監(jiān)視器工具可供選擇。