目錄
整體架構(gòu)
馮若依曼模型
- 電腦指令執(zhí)行的過程
- CPU從PC(程序計數(shù)器)獲得指令內(nèi)存地址, 然后控制單元操作地址總線從內(nèi)存拿到數(shù)據(jù), 數(shù)據(jù)通過數(shù)據(jù)總線返回并存入指令CPU的寄存器中
- CPU分析指令寄存器中的指令, 如果是計算類型的指令交給邏輯運(yùn)算單元, 如果是存儲類型的指令交給控制單元執(zhí)行郑诺。
- CPU 執(zhí)行完指令后程序計數(shù)器的值通過自增指向下個指令, 不斷循環(huán)執(zhí)行直到程序結(jié)束
- x86架構(gòu)表示一系列指令集
多核cpu
-
參考參考文章1的圖, 圖介紹
- 寄存器: 最靠近CPU的存儲單元,訪問速度0.5個時鐘周期,時鐘也稱為定時器弃酌,cpu根據(jù)固定周期切換就是定時器其作用
- L1緩存: 各個cpu獨享嘁捷,緩存數(shù)據(jù)跟指令, 訪問速度2-4個時鐘周期
- L2緩存: 各個cpu獨享, 訪問速度10~20個時鐘周期
- L3緩存: 各個cpu共享, 訪問速度20~60個時鐘周期
- 內(nèi)存: 多個CPU共用,訪問速度是200~300個時鐘周期
- 固體硬盤SSD: SSD斷電不會丟數(shù)據(jù),比內(nèi)存慢10~1000倍
- 機(jī)械盤HDD: HDD斷電不會丟數(shù)據(jù)顷蟀,訪問速度比內(nèi)存慢10W倍
- Cache Line: CPU讀取數(shù)據(jù)是按照Cacheline = 64KB把數(shù)據(jù)加載到緩存中,所以L1绍赛,L2可能會觸發(fā)偽共享(將數(shù)據(jù)劃分到相同到CacheLine中, 當(dāng)多線程修改互相獨立的變量時蔓纠,如果這些變量共享同一個緩存行,就會影響彼此的性能)吗蚌。避免偽共享就是將數(shù)據(jù)劃分到不同的CacheLine中腿倚,JDK8 新增加的 LongAdder就是這塊知識。
- 大小從上到小一次增加蚯妇,訪問順序從上到下查找
如何盡可能提高CPU緩存命中率
- 數(shù)據(jù)緩存: 順序讀取能夠提升速度, 道理跟磁盤順序?qū)懸粯臃罅恰?shù)組就是連續(xù)內(nèi)存連續(xù)讀取。
- 指令緩存: CPU有分支預(yù)測器箩言,能提前將可能要的指令放到緩存區(qū)硬贯,所以盡提供有規(guī)律的條件分支語句,能幫助提高緩存命中率陨收。
- 線程綁定到CPU: 線程切換時每次切換回來用同一個核心CPU這樣能復(fù)用L1饭豹,L2緩存,也就是綁定線程到CPU提高性能务漩。
內(nèi)存管理
虛擬內(nèi)存
-
參考文章1的圖拄衰,操作系統(tǒng)會將進(jìn)程的虛擬地址做一個映射,映射到物理地址饵骨,這樣看起來每個進(jìn)程都是獨占系統(tǒng)了翘悉。32位系統(tǒng)最大支持4G, 因為尋址2的32次方,64位就能支持很大了宏悦。
內(nèi)存管理單元MMU(Memory Management Unit)
-
參考文章1的圖, MMU負(fù)責(zé): 虛擬地址到物理地址的轉(zhuǎn)換, 內(nèi)存保護(hù), 高速緩存控制镐确。 MMU一般封裝在CPU里面。
內(nèi)存管理方式
- 一般現(xiàn)在是使用分段和分頁來映射虛擬地址與物理地址之間的關(guān)系, 現(xiàn)在分頁用的最多饼煞。不過分段的話有個好處就是linux內(nèi)存布局中堆段數(shù)據(jù)段代碼段都可以動態(tài)拓展源葫。
頁式存儲管理
- 頁表實現(xiàn)虛擬內(nèi)存到物理內(nèi)存的映射,頁表保存在物理內(nèi)存中砖瞧。頁page一般都是4k, 每次釋放的時候都是按整個page來的息堂,所以就不會有內(nèi)存碎片的問題。當(dāng)內(nèi)存不夠時块促,操作系統(tǒng)會使用頁面置換算法荣堰,從物理內(nèi)存置換一片頁面出來。
- 內(nèi)存保護(hù)可以通過查頁表得知竭翠。
-
通過頁表映射虛擬地址到物理地址振坚,參考現(xiàn)代操作系統(tǒng)的圖,拿16位的舉例斋扰,前4位頁號作為頁表索引渡八,頁表中110 1中1表示在位啃洋,就是能映射到,如果不能映射到就可能產(chǎn)生缺頁中斷屎鳍。查到的頁框號高三位110和虛擬地址后12位結(jié)合產(chǎn)生物理地址宏娄。
- 32位操作系統(tǒng)占用4GB/4KB = 2^20 個頁信息, 一個頁4字節(jié),那2的20次方就是4Mb逮壁,如果有1000個進(jìn)程那頁表占用的內(nèi)存很大孵坚,常用解決方案是:
-
多級頁表(參考現(xiàn)代操作系統(tǒng)的圖): 避免不需要的頁表也放入內(nèi)存中,32位舉例窥淆,前10位PT1用作頂級頁表的索引卖宠,中間10位PT2用作二級頁表索引,映射到物理地址就跟只有一級頁表一樣祖乳。
- 內(nèi)存映射文件: 將文件映射到虛擬地址空間
加速訪問TLB(地址轉(zhuǎn)換后援緩沖器也叫快表)
-
TLB是MMU的一部分逗堵,緩存的是最近使用的數(shù)據(jù)的頁表項秉氧,參考現(xiàn)代操作系統(tǒng)的圖
頁面置換算法
- 當(dāng)發(fā)生缺頁中斷時眷昆,cpu TRAP指令陷入內(nèi)核,具體的linux使用頁面置換算法有:
- 最優(yōu): 標(biāo)記最后會被使用的頁面汁咏,這個實現(xiàn)不了
- FIFO: 先進(jìn)先出
- LRU: 最近最少訪問算法
- LFU: 最少訪問頻率算法
- linux使用的頁面置換算法, 改進(jìn)的LRU亚斋。
linux內(nèi)存管理圖
進(jìn)程管理
進(jìn)程跟線程的區(qū)別
- 進(jìn)程是系統(tǒng)調(diào)度資源的最小單位,進(jìn)程獨占系統(tǒng)資源攘滩,而線程缺占用很少的資源帅刊。
- 進(jìn)程由于資源比較多所以切換速度慢,線程資源少所以切換速度快漂问。
- 由于線程共享進(jìn)程資源所以線程通信方便赖瞒,進(jìn)程的IPC復(fù)雜一些。
進(jìn)程狀態(tài)圖
-
參考參考文章1的圖:
- 阻塞: 比如I/O阻塞蚤假,等待某個事件返回
- 掛起: 進(jìn)程從內(nèi)存中抽出栏饮,放入到磁盤
PCB(進(jìn)程控制塊)
- PCB屬于進(jìn)程實體一部分,操作系統(tǒng)中會記錄其數(shù)據(jù)結(jié)構(gòu)
- 作用:
- 獨立標(biāo)記一個進(jìn)程
- 進(jìn)程管理的依據(jù)
- 進(jìn)程調(diào)度的依據(jù)
- 進(jìn)程通信的依據(jù)
- 包含了:
- 進(jìn)程標(biāo)識符: 唯一標(biāo)識一個進(jìn)程
- 處理機(jī)狀態(tài): 記錄一些寄存器信息磷仰,cpu切換時restart用
- 進(jìn)程調(diào)度信息: 進(jìn)程優(yōu)先級之類的信息
- 資源清單: 所打開的文件句柄袍嬉,虛擬地址空間信息
PCB管理方式
-
進(jìn)程創(chuàng)建銷毀調(diào)度頻繁所以采用鏈表方式:
進(jìn)程控制
進(jìn)程創(chuàng)建
- 父進(jìn)程可以創(chuàng)建子進(jìn)程,子進(jìn)程繼承父進(jìn)程所有資源, 大致流程:
- 分配Pid唯一標(biāo)識號
- 分配所需資源
- 初始化PCB
- 資源允許的情況下進(jìn)入就緒隊列
進(jìn)程終止
- 分為正常結(jié)束, 異常結(jié)束(越界, I/O異常), 外界干預(yù)(操作系統(tǒng)干預(yù)灶平,父進(jìn)程終止伺通,父進(jìn)程請求)
- 終止大致過程:
- 根據(jù)標(biāo)識符,從PCB集合中找出該進(jìn)程PCB
- 執(zhí)行狀態(tài), 則直接終止, 如果有子進(jìn)程逢享,則等待子進(jìn)程終止
- 全部資源還給操作系統(tǒng)或者父進(jìn)程
- 從PCB鏈表中移除
進(jìn)程調(diào)度
- 搶占式:CPU時間片輪轉(zhuǎn)的形式調(diào)度進(jìn)程罐监,防止某個進(jìn)程占用CPU開銷很大。
- 調(diào)度算法:
- FCFS 算法: First Come First Severd瞒爬,類似FIFO算法弓柱,對長作業(yè)有利调缨,不適合I/O密集型
- SJF算法: Shortest Job First 最短作業(yè)優(yōu)先算法, 對短作業(yè)有利
- HRRN算法: Highest Response Ratio Next 最高響應(yīng)比優(yōu)先算法, 1,2的折中,按照響應(yīng)優(yōu)先級來的
- RR算法: Round Robin 時間片輪轉(zhuǎn)算法, 每個進(jìn)程都按照固定的時間片運(yùn)行吆你,輪流運(yùn)轉(zhuǎn)
- HPF算法: Highest Priority First 最高優(yōu)先級調(diào)度算法, 低優(yōu)先級的可能一直無法執(zhí)行
-
MFQ算法: Multilevel Feedback Queue 多級反饋隊列調(diào)度算法, 多個隊列中優(yōu)先級不同弦叶,優(yōu)先級高時間片短,新進(jìn)程會先加入到最高優(yōu)先級隊列妇多,下次執(zhí)行則進(jìn)程下一級優(yōu)先級隊列
進(jìn)程通信
- 進(jìn)程間相互獨立伤哺,但操作系統(tǒng)內(nèi)核是共享的,所以要通信必須走內(nèi)核者祖。
管道
- 匿名管道: 單向流動立莉,使用簡單,效率低七问。linux常用的|就是匿名管道蜓耻。實現(xiàn)依賴pipe。 本質(zhì)就是在內(nèi)核中弄個緩存械巡。通信范圍是父子進(jìn)程刹淌。
- 命名管道: 與匿名管道區(qū)別它有管道文件
消息隊列
- 它是保存在內(nèi)核的消息鏈表,傳遞消息需要用戶態(tài) -> 內(nèi)核態(tài) -> 核心態(tài)讥耗。消息有對應(yīng)的格式有勾,我們平常用的rocketmq, kafka也屬于消息隊列。
共享內(nèi)存
- 將一個公共部分比如文件映射到兩個不同進(jìn)程的虛擬地址古程,這時不涉及到用戶態(tài)核心態(tài)切換蔼卡,效率高。
信號量
- 整形的計數(shù)器挣磨,用于實現(xiàn)進(jìn)程間同步與互斥雇逞,可與共享內(nèi)存一起使用。信號量P茁裙,V
信號
- 異常狀態(tài)下需要用到信號通知進(jìn)程塘砸,信號是異步通信的,比如kill -9這種就是信號呜达,進(jìn)程可以響應(yīng)谣蠢,忽略信號,信號承載的信息少
socket
- 用于不同機(jī)器之前的通信
線程
-
線程狀態(tài)流轉(zhuǎn)圖查近,參考文獻(xiàn)3的圖, start方法使線程變成可運(yùn)行狀態(tài)眉踱,run方法只是一個普通方法可重復(fù)調(diào)用。線程中斷可以調(diào)用interrupt方法霜威,但是至于線程什么時候響應(yīng)谈喳,需要看具體代碼,這里只是發(fā)出中斷請求戈泼。不像cpu執(zhí)行完一行代碼就看下是否有需要響應(yīng)的中斷婿禽。
- 對于操作系統(tǒng)而言赏僧,每個進(jìn)程只有一個線程,因為每次調(diào)度都是這么調(diào)度的
- 進(jìn)程是PCB扭倾,線程是TCB淀零,也是操作系統(tǒng)能管,內(nèi)線程模式下一個用戶線程對應(yīng)一個內(nèi)核線程膛壹, java里面的線程與內(nèi)核線程一一對應(yīng)
- 輕量級線程本質(zhì)上還是進(jìn)程驾中,只是大部分?jǐn)?shù)據(jù)共享
- 協(xié)程運(yùn)行在線程之上,n個協(xié)程對應(yīng)一個線程
異常與中斷
- 中斷有專門的中斷控制器統(tǒng)一進(jìn)行處理模聋,并通知相應(yīng)設(shè)備肩民。中斷是處理器外部的中斷信號,異常是處理器內(nèi)部的內(nèi)中斷链方,內(nèi)中斷不能被屏蔽持痰,一旦出現(xiàn)必須立即予以響應(yīng)并進(jìn)行處理。
-
參考文章9的圖
switch if效率問題
- switch對于分支較多時效率高祟蚀,用空間換時間工窍,直接類似數(shù)組讀取對應(yīng)分支,不需要一個個判斷暂题。常量分布范圍很大但實際有效值又比較少的情況移剪,switch空間利用率較低。
- if需要一個個分支判斷薪者,但是if更靈活,可用作范圍判斷剿涮,switch只能是常量言津。
文件管理
-
參考文章1的圖,虛擬文件系統(tǒng)定義了用戶態(tài)可以訪問的POSIX(可移植操作系統(tǒng)接口),
- 常用的文件系統(tǒng)分三種:
- 磁盤文件系統(tǒng): EXT3之類
- 內(nèi)存文件系統(tǒng): 占用內(nèi)存數(shù)據(jù)取试,/sys之類的
- 網(wǎng)絡(luò)文件系統(tǒng):常見的網(wǎng)盤掛載NFS
- 拓展: fat: u盤使用悬槽,NTFS: 對應(yīng)u盤或者硬盤而言使用最廣的
文件組成
- 重要的有兩部分: inode節(jié)點和目錄項
inode
- 文件存儲最小單位是扇區(qū),一般讀取時會多個扇區(qū)一起讀取瞬浓,這種就做塊初婆,塊是文件存儲的最小單位,文件信息都存儲在塊中猿棉,inode節(jié)點存儲了文件元數(shù)據(jù)信息磅叛,比如創(chuàng)建時間、inode編號萨赁、修改時間之類的弊琴,這些元數(shù)據(jù)信息存儲在索引節(jié)點inode里面。操作系統(tǒng)用inode號碼來識別不同的文件杖爽。對于操作系統(tǒng)而言文件名就是inode號碼別名敲董。
- iNode有個好處就是只有在文件打開時紫皇,iNode才在內(nèi)存里面
一次查找/usr/ast/mbox的過程
- 文件系統(tǒng)定位到根目錄/usr, 根目錄iNode放在固定的磁盤位置
- 查找usr得到iNode是6
- iNode 6說明usr在塊132上
- 根據(jù)第三步驟得到/usr/ast是iNode 26
- iNode 26說明/usr/ast在塊406中
- 從塊406得知/usr/ast/mbox的iNode是60
-
這個文件的iNode會被讀取到內(nèi)存中知道關(guān)閉
目錄
- 對于操作系統(tǒng)而言,目錄也是一種文件腋寨,為避免頻繁讀取磁盤里的目錄文件聪铺,內(nèi)核會把已經(jīng)讀過的目錄文件用目錄項這個數(shù)據(jù)結(jié)構(gòu)緩存在內(nèi)存
共享文件之軟鏈接和硬鏈接:
- 硬鏈接:兩個文件硬鏈接指的是兩個文件inode相同,所以不能跨文件系統(tǒng)萄窜。只有兩個文件刪除计寇,源文件才會被刪除。
- 軟鏈接:兩個文件軟鏈接指的是兩個文件有不同的iNode脂倦,所以軟鏈接可以跨文件系統(tǒng)番宁。某個文件刪除后,另個文件還存在不過找不到它了赖阻。
文件存儲
- 大文件一般用iNode節(jié)點能夠快速索引到具體的塊
- 小文件可以考慮用連續(xù)內(nèi)存類似數(shù)組蝶押,存儲塊
- 小文件也可以考慮用鏈表鏈接文件使用到的塊信息
- 操作系統(tǒng)存儲會根據(jù)文件大小改變存儲塊索引策略
空閑空間管理
- 管理空閑塊,這樣就不用一個個塊查找看下是否空閑火欧,然后放入文件里面的信息
- 類似redis的bitMap棋电,標(biāo)識是否存在,iNode用這個方法標(biāo)識
文件系統(tǒng)四大對象
-
要訪問文件苇侵,必須將文件掛載在目錄樹上面的目錄赶盔,掛載目錄稱為掛載點,文件系統(tǒng)磁盤上布局榆浓,圖是參考文章4的圖
- 引導(dǎo)塊: 引導(dǎo)操作系統(tǒng)用于未,一般啟動時用到
- 超級塊: 物理磁盤中文件系統(tǒng)結(jié)構(gòu)的相關(guān)信息
- i節(jié)點: iNode,文件系統(tǒng)元數(shù)據(jù)信息
輸入輸出管理
I/O控制器跟驅(qū)動程序
-
參考文章1的圖
- 設(shè)備控制器是為了屏蔽操作系統(tǒng)操作I/O設(shè)備的細(xì)節(jié)陡鹃,統(tǒng)一接口烘浦。輸入輸出設(shè)備可分為塊設(shè)備跟字符設(shè)備,塊設(shè)置是落盤的萍鲸,比如磁盤闷叉,字符設(shè)備不落盤,比如鼠標(biāo)
- CPU通過IO端口跟內(nèi)存映射IO來跟I/O設(shè)備控制器中寄存器緩沖區(qū)通信
- 內(nèi)存映射IO:設(shè)備控制中的寄存器映射到內(nèi)存里脊阴,讀寫內(nèi)存就可以讀寫設(shè)備控制器的緩沖區(qū)
驅(qū)動接口與設(shè)備控制器
-
參考文章1的圖握侧,驅(qū)動程序屏蔽了I/O外設(shè)設(shè)備控制器中寄存器使用細(xì)節(jié),給操作系統(tǒng)提供統(tǒng)一接口
I/O控制
-
cpu與設(shè)備控制器交互讀取數(shù)據(jù)流程嘿期,DMA參與后續(xù)流程品擎,完成后通過中斷通知Cpu, DMA減輕了CPU負(fù)擔(dān)。有DMA在所以I/O不會一直占用CPU秽五。
0拷貝
老式讀寫
-
從磁盤到網(wǎng)絡(luò)數(shù)據(jù)傳輸?shù)睦鲜阶x寫孽查,參考文章1的圖,真?zhèn)€過程4次用戶態(tài)跟內(nèi)核態(tài)的切換坦喘,2次DMA數(shù)據(jù)拷貝盲再,2次CPU數(shù)據(jù)拷貝西设。
mmap
-
參考文章1的圖, 主要的優(yōu)化是3共享緩存,減少了數(shù)據(jù)復(fù)制的次數(shù)
sendfile
-
在mmap的基礎(chǔ)之上減少了上下文切換答朋,實際工作中一般小文件采用0拷貝技術(shù)贷揽,而大文件會用異步IO。因為第2步梦碗,DMA將數(shù)據(jù)拷貝到內(nèi)核緩存區(qū)禽绪,這個內(nèi)核緩存區(qū)就是頁P(yáng)age, PageCache。頁緩存大小有限洪规,所以大文件不走這種形式印屁。
I/O分層
-
參考文章1的圖
- 讀取數(shù)據(jù)是之上而下的, I/O分層主要分以下三層
- 文件系統(tǒng)層提供統(tǒng)一文件訪問接口
- 通用塊層包括塊設(shè)備的 I/O 隊列和 I/O 調(diào)度器。
- 設(shè)備層有設(shè)備控制器和驅(qū)動程序給最底層打交道斩例。
死鎖
死鎖的產(chǎn)生條件
- 資源非搶占式
- 資源互斥
- 請求資源并保持
- 循環(huán)等待
死鎖檢測
-
有向圖雄人,根據(jù)資源分配有向圖可以檢測出死鎖
死鎖的避免
- 銀行家算法:一個人去銀行借錢的時候,聲明借錢的數(shù)量念赶,聲明歸還時間础钠,銀行審批通過則借貸.其實就是資源合理分配,并對資源進(jìn)行安全性檢查. 安全性檢查其實就是所用請求當(dāng)前資源的總和不超過當(dāng)前可借貸的資源. 可重入鎖也可預(yù)防叉谜,同一線程外層函數(shù)獲得鎖之后旗吁,內(nèi)層遞歸函數(shù)依然有獲取該鎖的代碼,但不影響停局。
死鎖預(yù)防
- 破壞不可搶占條件:允許對資源實行搶奪很钓。
- 破壞循環(huán)等待條件:對系統(tǒng)所有資源進(jìn)行線性排序并賦予不同的序號,這樣我們便可以規(guī)定進(jìn)程在申請資源時必須按照序號遞增的順序進(jìn)行資源的申請翻具,當(dāng)以后要申請時需檢查要申請的資源的編號大于當(dāng)前編號時履怯,才能進(jìn)行申請。
- 破壞請求和保持條件:要求每個進(jìn)程提出新的資源申請前裆泳,釋放它所占有的資源。這樣柠硕,一個進(jìn)程在需要資源S時工禾,需要先把它先前占有的資源R釋放掉,然后才能提出對S的申請蝗柔,即使它很快又要用到資源R闻葵。