問題出現(xiàn)的原因是Synchronize和ReentrantLock二者的都會(huì)阻塞線程囚戚,并且阻塞和喚醒的代價(jià)高
操作系統(tǒng)需要在用戶態(tài)與內(nèi)核態(tài)之間來回切換酵熙,代價(jià)很高,不過可以通過對(duì)鎖優(yōu)化進(jìn)行改善
用戶態(tài)和內(nèi)核態(tài): 內(nèi)核從本質(zhì)上看是一種軟件——控制計(jì)算機(jī)的硬件資源驰坊,并提供上層應(yīng)用程序運(yùn)行的環(huán)境匾二。用戶態(tài)即上層應(yīng)用程序的活動(dòng)空間,應(yīng)用程序的執(zhí)行必須依托于內(nèi)核提供的資源拳芙,包括CPU資源察藐、存儲(chǔ)資源、I/O資源等舟扎。為了使上層應(yīng)用能夠訪問到這些資源分飞,內(nèi)核必須為上層應(yīng)用提供訪問的接口:即系統(tǒng)調(diào)用。
損耗:幾十納秒到數(shù)微妙的CPU時(shí)間
- 上下文切換種類
1.線程切換-同一進(jìn)程中的兩個(gè)線程之間的切換
2.進(jìn)程切換-兩個(gè)進(jìn)程之間的切換
3.模式切換-在給定線程中睹限,用戶模式和內(nèi)核模式的切換
在上下文切換過程中譬猫,CPU會(huì)停止處理當(dāng)前運(yùn)行的程序,并保存當(dāng)前程序運(yùn)行的具體位置以便之后繼續(xù)運(yùn)行
在程序中上下文切換過程中的“頁碼”信息是保存在進(jìn)程控制塊
(PCB, process control block)羡疗,切換幀
PCB通常是系統(tǒng)內(nèi)存占用區(qū)中的一個(gè)連續(xù)存區(qū)染服,它存放著操作系統(tǒng)用于描述進(jìn)程情況及控制進(jìn)程運(yùn)行所需的全部信息
-上下文切換執(zhí)行步驟:
- 保存進(jìn)程A的狀態(tài)(寄存器和操作系統(tǒng)數(shù)據(jù));
- 更新PCB中的信息叨恨,對(duì)進(jìn)程A的“運(yùn)行態(tài)”做出相應(yīng)更改柳刮;
- 將進(jìn)程A的PCB放入相關(guān)狀態(tài)的隊(duì)列;
- 將進(jìn)程B的PCB信息改為“運(yùn)行態(tài)”,并執(zhí)行進(jìn)程B秉颗;
- B執(zhí)行完后痢毒,從隊(duì)列中取出進(jìn)程A的PCB,恢復(fù)進(jìn)程A被切換時(shí)的上下文站宗,繼續(xù)執(zhí)行A闸准;
- CPU 上下文切換:
把前一個(gè)任務(wù)的CPU上下文(CPU寄存器和程序計(jì)數(shù)器-內(nèi)核棧)保存,然后加載新任務(wù)的上下文到寄存器和程序計(jì)數(shù)器中梢灭,跳轉(zhuǎn)到程序計(jì)數(shù)器所指向的位置,開始執(zhí)行任務(wù)蒸其。 - 進(jìn)程切換:進(jìn)程資源(用戶態(tài)的虛擬內(nèi)存敏释、棧,內(nèi)核態(tài)的棧和硬件上下文-CPU寄存器)
1.切換頁目錄以使用新的地址空間(刷新新進(jìn)程的虛擬內(nèi)存和用戶棧摸袁,當(dāng)虛擬內(nèi)存更新后钥顽,TLB也需要更新)
2.切換內(nèi)核棧和硬件上下文 - 線程切換:
1.切換內(nèi)核棧和硬件上下文
線程的切換虛擬內(nèi)存空間依然是相同的(TLB),但是進(jìn)程切換是不同的
多線程上下文切換的主要損耗
linux2.6 jvm1.8采用的是1對(duì)1線程模型靠汁,線程調(diào)度是由os內(nèi)核完成(內(nèi)核態(tài))蜂大,同一個(gè)進(jìn)程種多線程的上下文切換不需要更新虛擬內(nèi)存,而且只有一次cpu上下文切換
有一點(diǎn)不能混淆:
cpu時(shí)間片蝶怔,不同進(jìn)程想要執(zhí)行必須獲得cpu時(shí)間片奶浦,這個(gè)是由內(nèi)核決定,完全公平調(diào)度
線程調(diào)度就是由內(nèi)核來完成的踢星,這個(gè)過程中澳叉,應(yīng)該涉及到的是內(nèi)核程序獲取cpu時(shí)間片,執(zhí)行內(nèi)核態(tài)操作沐悦,主要損耗是在cpu內(nèi)核和用戶進(jìn)程切換導(dǎo)致的損耗成洗,這個(gè)是無法避免的
一次系統(tǒng)調(diào)用主要損耗
從用戶態(tài)切換到內(nèi)核態(tài),需要通過系統(tǒng)調(diào)用的方式藏否。該過程也是有CPU上下文切換的:切換時(shí)瓶殃,先保存CPU寄存器中用戶態(tài)的指令位置,再重新更新為內(nèi)核指令的位置副签。當(dāng)系統(tǒng)調(diào)用結(jié)束時(shí)遥椿,CPU寄存器恢復(fù)到原來保存的用戶態(tài)。一次系統(tǒng)調(diào)用继薛,發(fā)生了兩次CPU上下文切換
修壕。
進(jìn)程切換主要損耗:
- 指的是CPU寄存器需要保存和加載(單純切換寄存器影響倒不是特別大)
- TLB(TLB是一種高速緩存,內(nèi)存管理硬件使用它來改善虛擬地址到物理地址的轉(zhuǎn)換速度)實(shí)例需要重新加載-這個(gè)對(duì)性能影響非常大不說遏考,整個(gè)進(jìn)程的執(zhí)行都會(huì)停止
- CPU 的pipeline需要刷掉(cpu 匯編代碼優(yōu)化-匯編代碼轉(zhuǎn)換成機(jī)器指令由硬件直接實(shí)現(xiàn)這一步速度是很快的)
- 調(diào)度器進(jìn)行線程調(diào)度
- 間接消耗:性能損失來源于緩沖區(qū)的復(fù)制慈鸠,多核cache的復(fù)制
補(bǔ)充:
1、對(duì)于一個(gè)正在執(zhí)行的進(jìn)程包括 程序計(jì)數(shù)器、寄存器青团、變量的當(dāng)前值等 譬巫,而這些數(shù)據(jù)都是 保存在CPU的寄存器中的,且這些寄存器只能是正在使用CPU的進(jìn)程才能享用督笆,在進(jìn)程切換時(shí)芦昔,首先得保存上一個(gè)進(jìn)程的這些數(shù)據(jù),然后將本次獲得CPU的進(jìn)程的這些數(shù)據(jù)裝入CPU的寄存器從上次斷點(diǎn)處繼續(xù)執(zhí)行剩下的任務(wù)娃肿。
2咕缎、當(dāng)程序中有系統(tǒng)調(diào)用語句,程序執(zhí)行到系統(tǒng)調(diào)用時(shí)料扰,首先使用類似int 80H的軟中斷指令凭豪,保存現(xiàn)場,去的系統(tǒng)調(diào)用號(hào)晒杈,在內(nèi)核態(tài)執(zhí)行嫂伞,然后恢復(fù)現(xiàn)場,每個(gè)進(jìn)程都會(huì)有兩個(gè)棧拯钻,一個(gè)內(nèi)核態(tài)棧和一個(gè)用戶態(tài)棧帖努。當(dāng)執(zhí)行int中斷執(zhí)行時(shí)就會(huì)由用戶態(tài),棧轉(zhuǎn)向內(nèi)核棧粪般,系統(tǒng)調(diào)用時(shí)需要進(jìn)行棧的切換拼余。
3、系統(tǒng)調(diào)用就會(huì)引起用戶態(tài)和內(nèi)核態(tài)的切換
系統(tǒng)調(diào)用一般都需要保存用戶程序得上下文(context), 在進(jìn)入內(nèi)核得時(shí)候需要保存用戶態(tài)得寄存器刊驴,在內(nèi)核態(tài)返回用戶態(tài)得時(shí)候會(huì)恢復(fù)這些寄存器得內(nèi)容姿搜。這是一個(gè)開銷的地方。 如果需要在不同用戶程序間切換的話捆憎,那么還要更新cr3寄存器舅柜,這樣會(huì)更換每個(gè)程序的虛擬內(nèi)存到物理內(nèi)存映射表的地址(PCB),也是一個(gè)比較高負(fù)擔(dān)的操作躲惰。
科普
寄存器是中央處理器內(nèi)的組成部份致份。寄存器是有限存貯容量的高速存貯部件,它們可用來暫存指令础拨、數(shù)據(jù)和位址氮块。在中央處理器的控制部件中,包含的寄存器有指令寄存器(IR)和程序計(jì)數(shù)器(PC)诡宗。在中央處理器的算術(shù)及邏輯部件中滔蝉,包含的寄存器有累加器(ACC)。
內(nèi)存包含的范圍非常廣塔沃,一般分為只讀存儲(chǔ)器(ROM)蝠引、隨機(jī)存儲(chǔ)器(RAM)和高速緩存存儲(chǔ)器(cache)。
寄存器是CPU內(nèi)部的元件,寄存器擁有非常高的讀寫速度螃概,所以在寄存器之間的數(shù)據(jù)傳送非辰煤唬快。
Cache :即高速緩沖存儲(chǔ)器吊洼,是位于CPU與主內(nèi)存間的一種容量較小但速度很高的存儲(chǔ)器训貌。由于CPU的速度遠(yuǎn)高于主內(nèi)存,CPU直接從內(nèi)存中存取數(shù)據(jù)要等待一定時(shí)間周期冒窍,Cache中保存著CPU剛用過或循環(huán)使用的一部分?jǐn)?shù)據(jù)递沪,當(dāng)CPU再次使用該部分?jǐn)?shù)據(jù)時(shí)可從Cache中直接調(diào)用,這樣就減少了CPU的等待時(shí)間,提高了系統(tǒng)的效率。Cache又分為一級(jí)Cache(L1 Cache)和二級(jí)Cache(L2 Cache)综液,L1 Cache集成在CPU內(nèi)部区拳,L2 Cache早期一般是焊在主板上,現(xiàn)在也都集成在CPU內(nèi)部,常見的容量有256KB或512KB L2 Cache意乓。
查看
cs列就是指上下文切換的數(shù)目. 一般情況下, 空閑系統(tǒng)的上下文切換每秒大概在1500以下.
vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 11080100 640552 45502336 0 0 72 323 0 0 13 3 84 0 0
0 0 0 11079984 640552 45502336 0 0 0 0 3233 5797 1 0 98 0 0
0 0 0 11079968 640552 45502336 0 0 0 0 2975 6137 1 0 99 0 0
1 0 0 11079984 640552 45502336 0 0 0 68 3870 6188 4 0 96 0 0
1 0 0 11080000 640552 45502336 0 0 0 4 3671 6122 2 0 98 0 0
0 0 0 11079860 640552 45502336 0 0 0 0 2900 6360 1 0 99 0 0
0 0 0 11079860 640552 45502336 0 0 0 0 3616 6021 2 0 98 0 0
0 0 0 11078776 640552 45502336 0 0 0 8 4062 7365 2 1 97 0 0
0 0 0 11078744 640552 45502336 0 0 0 64 2970 6091 1 0 99 0 0
1 0 0 11078760 640552 45502336 0 0 0 16 3764 6137 3 0 97 0 0
0 0 0 11078760 640552 45502336 0 0 0 0 3175 6207 1 0 99 0 0
0 0 0 11078744 640552 45502336 0 0 0 0 3011 6025 1 0 98 0 0
0 0 0 11079264 640552 45502328 0 0 0 44 4071 6573 2 0 97 0 0
感謝大神:
https://juejin.im/post/5b10e53b6fb9a01e5b10e9be#heading-14
https://blog.csdn.net/JH_Zhai/article/details/79861169
https://cloud.tencent.com/developer/article/1082708
https://my.oschina.net/u/4106059/blog/3029071
https://blog.csdn.net/Code_Hu/article/details/84632591