Linux操作系統(tǒng)
1.計(jì)算機(jī)工作模式
核心,和其它設(shè)備連接需要靠總線,另外很多復(fù)雜的計(jì)算任務(wù)需要將中間結(jié)果保存到內(nèi)存中,CPU包含三個(gè)部分
運(yùn)算單元 負(fù)責(zé)運(yùn)算
數(shù)據(jù)單元 暫存數(shù)據(jù)和運(yùn)算結(jié)果
控制單元 指揮做什么運(yùn)算
很多復(fù)雜的計(jì)算任務(wù)需要將中間結(jié)果保存到內(nèi)存中。
CPU和內(nèi)存?zhèn)鲾?shù)據(jù),靠的是總線。主要有兩類數(shù)據(jù),一個(gè)是地址數(shù)據(jù),也就是我想拿內(nèi)存中哪個(gè)位置的數(shù)據(jù),這類總線叫地址總線(Address Bus);另一類是真正的數(shù)據(jù),這類總線叫數(shù)據(jù)總線(Data Bus)。
地址總線的位數(shù),決定了能訪問的地址范圍到底有多廣。例如只有兩位,那CPU就只能認(rèn)00,01,10,11四個(gè)位置。
而數(shù)據(jù)總線的位數(shù),決定了一次能拿多少個(gè)數(shù)據(jù)進(jìn)來。例如只有兩位,那CPU一次只能從內(nèi)存拿兩位數(shù)。要想拿八位,就要拿四次。位數(shù)越多,一次拿的數(shù)據(jù)就越多,訪問速度也就越快
2.x86架構(gòu)
x86架構(gòu)起源于8086處理器:
AX、BX、CX、DX、SP、BP、SI、DI主要用來暫存數(shù)據(jù),其中AX、BX、CX、DX可以分成兩個(gè)8位的寄存器來使用。
IP寄存器:指向代碼段中下一條指令的位置。CPU會(huì)根據(jù)它來不斷地將指令從內(nèi)存的代碼段中,加載到CPU的指令隊(duì)列中,然后交給運(yùn)算單元去執(zhí)行
3.32位處理器
在32位處理器中,有32根地址總線,可以訪問2^32=4G的內(nèi)存
x86有兩種模式:
實(shí)模式,只能尋址1M,每個(gè)段最多64K
保護(hù)模式,對于32位系統(tǒng),能夠?qū)ぶ?G
4.BIOS
在主板上,有一個(gè)只讀的東西叫ROM,上面固化了一些初始化的程序,也就是BIOS。
4.進(jìn)程
5.線程
使用進(jìn)程的問題:
占用資源多
進(jìn)程通訊需要在不同的內(nèi)存空間傳來傳去,無法共享
線程的數(shù)據(jù)
線程棧上的本地?cái)?shù)據(jù)
在整個(gè)進(jìn)程里共享的全局?jǐn)?shù)據(jù)
線程私有數(shù)據(jù)(比如java里面的threadLocal)
6.內(nèi)存
電腦內(nèi)存16GB指的是物理內(nèi)存,只有內(nèi)核才可以訪問物理內(nèi)存。
進(jìn)程都有一個(gè)虛擬地址空間,訪問自己的虛擬內(nèi)存,虛擬地址空間又分為用戶空間和內(nèi)核空間。進(jìn)程在用戶態(tài)時(shí),只能訪問用戶空間內(nèi)存;只有進(jìn)入內(nèi)核態(tài)后,才可以訪問內(nèi)核空間內(nèi)存。并不是所有的虛擬內(nèi)存都會(huì)訪分配物理內(nèi)存,只要真正使用的才會(huì)分配。
MMU是CPU的內(nèi)存管理單元。TLB是 MMU 中頁表的高速緩存。由于進(jìn)程的虛擬地址空間是獨(dú)立的,而 TLB 的訪問速度又比 MMU 快得多,所以,通過減少進(jìn)程的上下文切換,減少 TLB 的刷新次數(shù),就可以提高 TLB 緩存的使用率,進(jìn)而提高 CPU 的內(nèi)存訪問性能。
虛擬內(nèi)存空間分為:
只讀段,包括代碼和常量等。
數(shù)據(jù)段,包括全局變量等。
堆,包括動(dòng)態(tài)分配的內(nèi)存,從低地址開始向上增長。
文件映射段,包括動(dòng)態(tài)庫、共享內(nèi)存等,從高地址開始向下增長。
棧,包括局部變量和函數(shù)調(diào)用的上下文等。棧的大小是固定的,一般是 8 MB。
在這五個(gè)內(nèi)存段中,堆和文件映射段的內(nèi)存是動(dòng)態(tài)分配的。比如說,使用 C 標(biāo)準(zhǔn)庫的 malloc() 或者 mmap() ,就可以分別在堆和文件映射段動(dòng)態(tài)分配內(nèi)存
對小塊內(nèi)存(小于 128K)
C 標(biāo)準(zhǔn)庫使用 brk() 來分配,可以減少缺頁異常的發(fā)生,但是頻繁的內(nèi)存分配和釋放會(huì)造成內(nèi)存碎片
brk分配的內(nèi)存是推_edata指針,從堆的低地址向高地址推進(jìn)。這種情況下,如果高地址的內(nèi)存不釋放,低地址的內(nèi)存是得不到釋放的
而大塊內(nèi)存(大于 128K)
直接使用內(nèi)存映射 mmap() 來分配,會(huì)在釋放時(shí)直接歸還系統(tǒng),所以每次 mmap 都會(huì)發(fā)生缺頁異常
用戶空間的內(nèi)存分配都是基于buddy算法(伙伴算法),并不涉及slab
發(fā)現(xiàn)內(nèi)存緊張時(shí),系統(tǒng)就會(huì)通過一系列機(jī)制來回收內(nèi)存,比如
回收不常訪問的內(nèi)存,把不常用的內(nèi)存通過交換分區(qū)直接寫到磁盤中,Swap 其實(shí)就是把一塊磁盤空間當(dāng)成內(nèi)存來用。它可以把進(jìn)程暫時(shí)不用的數(shù)據(jù)存儲(chǔ)到磁盤中(這個(gè)過程稱為換出),當(dāng)進(jìn)程訪問這些內(nèi)存時(shí),再從磁盤讀取這些數(shù)據(jù)到內(nèi)存中(這個(gè)過程稱為換入)。通常只在內(nèi)存不足時(shí),才會(huì)發(fā)生 Swap 交換。并且由于磁盤讀寫的速度遠(yuǎn)比內(nèi)存慢,Swap 會(huì)導(dǎo)致嚴(yán)重的內(nèi)存性能問題。
OOM,直接殺掉占用大量內(nèi)存的進(jìn)程
[work(caibin)@tjtx167-39-49 ~]$ free total used free shared buffers cached Mem: 131356876 127138940 4217936 5266204 1292 82237136 -/+ buffers/cache: 44900512 86456364 Swap: 0 0 0
1
2
3
4
5
1
2
3
4
5
Buffer 是對磁盤數(shù)據(jù)的緩存,通常不會(huì)特別大(20MB 左右)。這樣,內(nèi)核就可以把分散的寫集中起來,統(tǒng)一優(yōu)化磁盤的寫入,比如可以把多次小的寫合并成單次大的寫等等。
而 Cache 是文件數(shù)據(jù)的緩存,它們既會(huì)用在讀請求中,也會(huì)用在寫請求中。是從磁盤讀取文件的頁緩存,也就是用來緩存從文件讀取的數(shù)據(jù)。這樣,下次訪問這些文件數(shù)據(jù)時(shí),就可以直接從內(nèi)存中快速獲取,而不需要再次訪問緩慢的磁盤。
Buffer主要是讀寫磁盤時(shí)緩存,Cache主要是讀寫文件時(shí)緩存。
Swap 說白了就是把一塊磁盤空間或者一個(gè)本地文件,當(dāng)成內(nèi)存來使用
Swap 把這些不常訪問的內(nèi)存先寫到磁盤中,然后釋放這些內(nèi)存,給其他更需要的進(jìn)程使用。再次訪問這些內(nèi)存時(shí),重新從磁盤讀入內(nèi)存就可以了。
Java 的應(yīng)用都建議關(guān) swap,這個(gè)和 JVM 的 gc 有關(guān),它在 gc 的時(shí)候會(huì)遍歷所有用到的堆的內(nèi)存,如果這部分內(nèi)存是被 swap 出去了,遍歷的時(shí)候就會(huì)有磁盤IO
什么時(shí)候發(fā)出swap呢?
有新的大塊內(nèi)存分配請求,但是剩余內(nèi)存不足。這個(gè)時(shí)候系統(tǒng)就需要回收一部分內(nèi)存(比如前面提到的緩存),進(jìn)而盡可能地滿足新內(nèi)存請求。這個(gè)過程通常被稱為直接內(nèi)存回收。
kswapd0 定義了三個(gè)閾值(可以手動(dòng)修改):
頁最小閾值(pages_min)
頁低閾值(pages_low)
頁高閾值(pages_high)
剩余內(nèi)存,則使用 pages_free 表示。
剩余內(nèi)存小于頁最小閾值,說明進(jìn)程可用內(nèi)存都耗盡了,只有內(nèi)核才可以分配內(nèi)存。
剩余內(nèi)存落在頁最小閾值和頁低閾值中間,說明內(nèi)存壓力比較大,剩余內(nèi)存不多了。這時(shí) kswapd0 會(huì)執(zhí)行內(nèi)存回收,直到剩余內(nèi)存大于高閾值為止。
剩余內(nèi)存落在頁低閾值和頁高閾值中間,說明內(nèi)存有一定壓力,但還可以滿足新內(nèi)存請求。
剩余內(nèi)存大于頁高閾值,說明剩余內(nèi)存比較多,沒有內(nèi)存壓力
明明發(fā)現(xiàn)了 Swap 升高,可是在分析系統(tǒng)的內(nèi)存使用時(shí),卻很可能發(fā)現(xiàn),系統(tǒng)剩余內(nèi)存還多著呢。為什么剩余內(nèi)存很多的情況下,也會(huì)發(fā)生 Swap 呢?
NUMA架構(gòu)下的處理器是多Node模式,每個(gè)Node都有自己的本地內(nèi)存空間。分析時(shí)需要每個(gè)Node單獨(dú)分析。
當(dāng)然,某個(gè) Node 內(nèi)存不足時(shí),系統(tǒng)可以從其他 Node 尋找空閑內(nèi)存,也可以從本地內(nèi)存中回收內(nèi)存。具體選哪種模式,你可以通過 /proc/sys/vm/zone_reclaim_mode 來調(diào)整。
對文件頁的回收,當(dāng)然就是直接回收緩存,或者把臟頁寫回磁盤后再回收。
而對匿名頁的回收,其實(shí)就是通過 Swap 機(jī)制,把它們寫入磁盤后再釋放內(nèi)存。
linux 提供了一個(gè) /proc/sys/vm/swappiness 選項(xiàng),用來調(diào)整使用 Swap 的積極程度。
swappiness 的范圍是 0-100,數(shù)值越大,越積極使用 Swap,也就是更傾向于回收匿名頁;數(shù)值越小,越消極使用 Swap,也就是更傾向于回收文件頁。
雖然 swappiness 的范圍是 0-100,不過要注意,這并不是內(nèi)存的百分比,而是調(diào)整 Swap 積極程度的權(quán)重
7.網(wǎng)絡(luò)
C10K 并發(fā)連接 1 萬
C10K 并發(fā)連接 10 萬
C1000K 并發(fā)連接 100 萬
C10K物理資源是足夠的,可以通過IO模型來實(shí)現(xiàn)C10K
可以通過IO模型來實(shí)現(xiàn)C100K
除了 I/O 模型之外,還需要從應(yīng)用程序到 linux 內(nèi)核、再到 CPU、內(nèi)存和網(wǎng)絡(luò)等各個(gè)層次的深度優(yōu)化。
Linux 任務(wù)調(diào)度
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。