通過日常使用電腦,我們大概都知道一個(gè)機(jī)器大概的結(jié)構(gòu)由CPU、內(nèi)存、硬盤以及外設(shè)構(gòu)成,那么Linux服務(wù)器也一樣,從上一章內(nèi)容知道,我們平常關(guān)注的系統(tǒng)性能差不多就是這些地方,那么,我們的進(jìn)程是如何在Linux上運(yùn)行的呢?一、進(jìn)程運(yùn)行過程首先,我們的數(shù)據(jù)是存放于磁盤/NAS等存儲(chǔ)目錄當(dāng)中,當(dāng)需要使用這些數(shù)據(jù)的時(shí)候,則要將數(shù)據(jù)從磁盤中讀取出來,經(jīng)過內(nèi)存再到三級(jí)緩存,然后進(jìn)入到CPU中。如下圖,數(shù)據(jù)從底部的存儲(chǔ)設(shè)備一步一步的被送進(jìn)入到CPU中。其用于傳輸數(shù)據(jù)的方式:遠(yuǎn)程存儲(chǔ)到本地二級(jí)存儲(chǔ)走的是網(wǎng)絡(luò)通信的方式,而本地存儲(chǔ)的數(shù)據(jù)進(jìn)入到內(nèi)存、CPU走的是BUS總線的方式。
進(jìn)程啟動(dòng)以后,其數(shù)據(jù)被從磁盤中讀取到內(nèi)存里緩存,當(dāng)CPU使用到它的時(shí)候,再被通過三級(jí)高速緩存送入到CPU中執(zhí)行。那么當(dāng)這個(gè)進(jìn)程被送入到CPU中運(yùn)行,是不是就可以一個(gè)人獨(dú)占CPU資源,直到跑完為止呢?不是的,現(xiàn)代系統(tǒng)設(shè)計(jì)出了上下文切換的模式,每個(gè)進(jìn)程運(yùn)行的時(shí)候都會(huì)分配到了一個(gè)時(shí)間片,當(dāng)這個(gè)時(shí)間片用完,那么當(dāng)前正在運(yùn)行的進(jìn)程就會(huì)保留當(dāng)前的狀態(tài)進(jìn)入到緩存當(dāng)中,當(dāng)再次輪到該進(jìn)程使用CPU的時(shí)候,才會(huì)從緩存當(dāng)中被讀取出來。通過這樣反復(fù)的切換,直到進(jìn)程運(yùn)行結(jié)束。但是我們?cè)谑褂眠M(jìn)程時(shí),為什么沒有進(jìn)程切換的感覺呢?那是因?yàn)镃PU的時(shí)間片以非常小的時(shí)間單位工作著,人們根本感受不到他的切換頻率。在Linux系統(tǒng)中存在著兩個(gè)空間,一個(gè)是用戶空間,另外一個(gè)就是內(nèi)核空間。用戶空間指的是用戶可以操作和訪問的空間,這個(gè)空間通常存放我們用戶自己寫的數(shù)據(jù)等,比如磁盤NAS就是屬于用戶空間。內(nèi)核空間就是系統(tǒng)內(nèi)核來操作的一塊空間,這塊空間里面存放系統(tǒng)內(nèi)核的函數(shù)、接口等,用戶是不能直接操作的。當(dāng)程序在用戶空間下運(yùn)行,我們把此時(shí)運(yùn)行的程序的這種狀態(tài)稱為用戶態(tài),而當(dāng)進(jìn)程執(zhí)行在內(nèi)核空間時(shí),這種狀態(tài)稱為內(nèi)核態(tài)。要想讓程序從用戶態(tài)切換到內(nèi)核態(tài),有3種方法:1.系統(tǒng)調(diào)用 (軟中斷)2.異常(硬中斷) 3.外圍設(shè)備的中斷(硬中斷)。二、進(jìn)程異常會(huì)遇到什么?進(jìn)程在運(yùn)行過程中不是一開始就知道使用多少內(nèi)存的,在持續(xù)的運(yùn)行過程中,會(huì)不斷的向系統(tǒng)申請(qǐng)內(nèi)存。當(dāng)有應(yīng)用需要讀寫磁盤數(shù)據(jù)時(shí),由系統(tǒng)把相關(guān)數(shù)據(jù)從磁盤讀取到內(nèi)存,如果物理內(nèi)存不夠,則把內(nèi)存中的部分?jǐn)?shù)據(jù)導(dǎo)入到磁盤,從而把磁盤的部分空間當(dāng)做虛擬內(nèi)存使用,這部分被稱為swap。如果給所有應(yīng)用分配足夠內(nèi)存后,物理內(nèi)存還有剩余,Linux會(huì)盡量再利用這些空閑內(nèi)存,以提高整體I/O效率,方法是把這部分剩余內(nèi)存再劃分為cache和buffer加以利用。如果某個(gè)時(shí)刻,系統(tǒng)需要更多的內(nèi)存,則會(huì)把cache部分擦除,并把buffer中的內(nèi)容寫入到磁盤中,然后把這兩部分的空間釋放給系統(tǒng)使用,但是再次讀取cache的內(nèi)容時(shí),就需要重新從磁盤讀取數(shù)據(jù)。下圖是系統(tǒng)中存在的緩存,當(dāng)系統(tǒng)需要內(nèi)存時(shí),就會(huì)被釋放空間,然后充當(dāng)內(nèi)存使用。
1) Page cache主要用來作為文件系統(tǒng)上的文件數(shù)據(jù)緩存來用,尤其是對(duì)當(dāng)進(jìn)程對(duì)文件有read/write操作的時(shí)候。2) Buffer cache主要是用來在系統(tǒng)對(duì)塊設(shè)備進(jìn)行讀寫的時(shí)候,對(duì)塊設(shè)備進(jìn)行數(shù)據(jù)緩存來使用。3) directory cacha的作用是作為目錄緩存,避免經(jīng)常訪問目錄慢。4) iNode cache則能夠加速訪問文件速度。同一系統(tǒng)內(nèi)的文件具有唯一識(shí)別碼,這個(gè)就是iNode號(hào)。查找文件的時(shí)候會(huì)先查詢?cè)撐募膇Node號(hào),再根據(jù)iNode號(hào)定位到文件位置。一般可以理解為buffer是為了作為數(shù)據(jù)寫入磁盤時(shí)的一個(gè)緩沖地帶。把分散的寫操作集中進(jìn)行,減少磁盤碎片和硬盤的反復(fù)尋道,從而提高系統(tǒng)性能。而cache經(jīng)常被用于磁盤的I/O請(qǐng)求上,如果多個(gè)進(jìn)程都有訪問某個(gè)文件,于是該文件便被作為cache以方便下次被訪問,這樣可以提高系統(tǒng)性能。
三、當(dāng)運(yùn)行一個(gè)進(jìn)程時(shí)系統(tǒng)內(nèi)存不夠會(huì)怎么樣?
在工作中會(huì)遇到這樣的場景:假設(shè)我的服務(wù)器就只有32G內(nèi)存,當(dāng)前以及使用了28G,而現(xiàn)在需要再運(yùn)行一個(gè)需要10G內(nèi)存的進(jìn)程,那么會(huì)發(fā)生什么呢?
如果這個(gè)進(jìn)程沒有做什么優(yōu)先級(jí)設(shè)定,那么這個(gè)進(jìn)程會(huì)觸發(fā)OOM,然后被系統(tǒng)kill掉。
什么是OOM?
OOM的全稱是Out of memory Killer,叫內(nèi)存終結(jié)者。在內(nèi)存過低的情況下,OS(系統(tǒng))會(huì)殺掉你的進(jìn)程。當(dāng)探測(cè)到內(nèi)存使用不足的時(shí)候,OOM會(huì)被激活,然后挑選一個(gè)進(jìn)程去終結(jié)掉。選擇的目標(biāo)進(jìn)程使用的是一套算法,后面會(huì)說。
進(jìn)程在運(yùn)行過程中是怎么使用內(nèi)存的呢?Linux允許程序申請(qǐng)比系統(tǒng)可用內(nèi)存更多的內(nèi)存,這個(gè)機(jī)制叫做Overcommit。這樣做是處于優(yōu)化系統(tǒng)考慮,因?yàn)椴皇撬械某绦蛏暾?qǐng)了內(nèi)存就立刻使用的,當(dāng)開始使用的時(shí)候,可能系統(tǒng)已經(jīng)回收了一些資源,但是當(dāng)使用overcommit給的內(nèi)存時(shí),系統(tǒng)還沒有資源的話,這個(gè)時(shí)候就會(huì)觸發(fā)OOM,然后干掉進(jìn)程。
有的時(shí)候在系統(tǒng)內(nèi)存不是很充足的情況下需要運(yùn)行一個(gè)重要的程序,那么該如何避免此程序被OOM干掉呢?
調(diào)整進(jìn)程的oom_adj值:Linux下每個(gè)進(jìn)程都有個(gè)OOM權(quán)重,在/proc/$pid/oom_adj里面,取值-17~+15,取值越高,越容易被干掉。
OOM Killer最終是通過/proc/$pid/oom_score這個(gè)值來決定哪個(gè)進(jìn)程被干掉。這個(gè)值是系統(tǒng)綜合進(jìn)程的內(nèi)存消耗量、CPU時(shí)間、存活時(shí)間和oom_adj計(jì)算出來的。消耗內(nèi)存越多分越高,存活時(shí)間越長分越低。總之。總的策略就是:損失最少的工作,釋放最大的內(nèi)存同時(shí)不傷及無辜的用來很大內(nèi)存的進(jìn)程,并且殺掉的進(jìn)程數(shù)盡量少。另外,Linux在計(jì)算進(jìn)程的內(nèi)存消耗的時(shí)候,會(huì)將子進(jìn)程所耗內(nèi)存的一半同時(shí)計(jì)算到父進(jìn)程中,這樣子進(jìn)程較多的進(jìn)程就越容易被殺掉。
在Linux中如何查看是否有進(jìn)程被OOM干掉了呢?
運(yùn)行dmesg即可查詢到,或者到/var/log/messages中查看。從網(wǎng)上找了個(gè)OOM的圖:
-
cpu
+關(guān)注
關(guān)注
68文章
10932瀏覽量
213544 -
Linux
+關(guān)注
關(guān)注
87文章
11358瀏覽量
210880 -
服務(wù)器
+關(guān)注
關(guān)注
12文章
9379瀏覽量
86320
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
如何評(píng)價(jià)《Linux就該這么學(xué)》這本書?
3516 L1 Linux版本成功啟動(dòng)!可以愉快地玩耍了~
到底是學(xué)STM32還是學(xué)嵌入式linux
什么是嵌入式Linux?
Linux到底是怎么樣來的?發(fā)展過程是如何的
Linux內(nèi)核到底是什么應(yīng)該如何學(xué)習(xí)
Linux到底是如何收發(fā)網(wǎng)絡(luò)包的

評(píng)論