linux系統(tǒng)編程-內(nèi)存管理day05

內(nèi)存鎖定

linux實(shí)現(xiàn)了請(qǐng)求頁面調(diào)度(在需要時(shí)將頁面從硬盤交換進(jìn)來汉嗽,當(dāng)不再需要時(shí)再交換出去)呀闻,這使得系統(tǒng)中進(jìn)程的虛擬地址空間與實(shí)際的物理內(nèi)存大小沒有直接的關(guān)系厨相。
交換對(duì)進(jìn)程來說是透明的炼七,應(yīng)用程序一般都不需要關(guān)心內(nèi)核頁面調(diào)度的行為。然而在下面兩種情況下虱朵,應(yīng)用程序可能希望影響系統(tǒng)的頁面調(diào)度:

  • 確定性時(shí)間約束嚴(yán)格的應(yīng)用程序需要自己來決定頁的調(diào)度行為莉炉。
  • 安全性:如果內(nèi)存中含有私人信息,這些信息可能最終被頁面調(diào)度以不加密的方式儲(chǔ)存到硬盤上碴犬。在一個(gè)高度注重安全性的環(huán)境中絮宁,這樣做可能是不可接收的。這樣的應(yīng)用程序可以請(qǐng)求將密鑰一直保留在物理內(nèi)存上翅敌。

  • 注意:雖然內(nèi)核提供了內(nèi)存鎖定的功能供應(yīng)用程序在需要的時(shí)候使用羞福,但是改變內(nèi)核的行為可能會(huì)對(duì)系統(tǒng)整體的表現(xiàn)產(chǎn)生負(fù)面的影響惕蹄。應(yīng)用的確定性和安全性可能會(huì)提高蚯涮,但是當(dāng)它的頁被鎖在了內(nèi)存中治专,那另一個(gè)應(yīng)用的頁就只能被換出內(nèi)存。所以遭顶,我們應(yīng)該有選擇的去使用內(nèi)存鎖定张峰,而不能盲目地使用。

鎖定部分地址空間

POSIX1003.1b-1993定義兩個(gè)接口將一個(gè)或多個(gè)頁面“鎖定”在物理內(nèi)存棒旗,來保證它們不會(huì)被交換到磁盤喘批。

  1. mlock( ):
    mlock( )鎖定給定的一個(gè)地址空間:
#include <sys/mman.h>
int mlock(const void *addr, size_t len);

調(diào)用mlock( )將鎖定addr開始長度為len個(gè)字節(jié)的虛擬內(nèi)存。成功時(shí)函數(shù)返回0,失敗返回-1,并適當(dāng)設(shè)置errno铣揉。

  • 成功調(diào)用會(huì)將所有包含[addr, addr+len)的物理內(nèi)存頁鎖定饶深。(例如,一個(gè)調(diào)用只是指定了一個(gè)字節(jié)逛拱,包含這個(gè)字節(jié)的所有物理內(nèi)存頁都將被鎖定)敌厘。
  • POSIX標(biāo)準(zhǔn)要求addr應(yīng)該與頁邊界對(duì)齊。Linux沒有強(qiáng)制要求朽合,如果真要這樣做的時(shí)候俱两,會(huì)悄悄的將addr向下調(diào)整到最近的頁面。
  • 一個(gè)由fork( )產(chǎn)生的子進(jìn)程并不從父進(jìn)程處繼承鎖定的內(nèi)存曹步。然而宪彩,由于Linux對(duì)地址空間COW機(jī)制,子進(jìn)程的頁面被鎖定在內(nèi)存中直到子進(jìn)程對(duì)它們執(zhí)行寫操作讲婚。
  1. mlockall( ):
    如果一個(gè)進(jìn)程想在物理內(nèi)存中鎖定它的全部地址空間尿孔,可以使用mlockall( ):
#include <sys/mman.h>
int mlockall(int flags);

mlockall( )函數(shù)鎖定一個(gè)進(jìn)程現(xiàn)有的地址空間在物理內(nèi)存中的所有頁面。
flags參數(shù)筹麸,是下面兩個(gè)值的按位或操作纳猫,用以控制函數(shù)行為:(大部分應(yīng)用程序會(huì)同時(shí)設(shè)定這兩個(gè)值)

  • MCL_CURRENT: 如果設(shè)置了該值,mlockall( )會(huì)將所有已被映射的頁面(包括棧竹捉,數(shù)據(jù)段芜辕,映射文件)鎖定進(jìn)程地址空間中。
  • MCL_FUTURE: 如果設(shè)置了該值块差,mlockall( )會(huì)將所有未來映射的頁面也鎖定到進(jìn)程地址空間中侵续。

內(nèi)存解鎖

POSIX標(biāo)準(zhǔn)提供了兩個(gè)接口用來將頁從內(nèi)存中解鎖,允許內(nèi)核根據(jù)需要將頁換出至硬盤中憨闰。

#include <sys/mman.h>
int munlock(const void *addr, size_t len);
in munlockall(void);
  • munlock( )解除addr開始長為len的內(nèi)存所在的頁面地鎖定状蜗,它消除mlock( )的效果.
  • munlockall( )消除mlockall( )的效果.
    兩個(gè)函數(shù)在成功時(shí)都返回0,失敗時(shí)返回-1.

內(nèi)存鎖定并不會(huì)重疊鹉动,所以不管mlock( )或mlockall( )了幾次轧坎,僅一個(gè)munlock( )或munlockall( )會(huì)解除一個(gè)頁面的鎖定。

linux對(duì)于一個(gè)進(jìn)程能鎖定的頁面數(shù)進(jìn)行了限制:擁有CAP_IPC_LOCK權(quán)限的進(jìn)程能鎖定任意多的頁面泽示。沒有這個(gè)權(quán)限的進(jìn)程只能鎖定RLIMIT_MEMLOCK個(gè)字節(jié)缸血,默認(rèn)情況下蜜氨,該限制是32KB


判斷一個(gè)頁面在不在物理內(nèi)存中

mincore( )函數(shù)捎泻,用來確定一個(gè)給定范圍的內(nèi)存是在物理內(nèi)存中還是被交換到了硬盤中:

#include <unistd.h>
#include <sys/mman.h>
int mincore(void *start, size_t length, unsigned char *vec);

函數(shù)通過vec來返回向量飒炎,這個(gè)向量描述start(必須頁面對(duì)齊)開始長為length(不需要對(duì)齊)字節(jié)的內(nèi)存中的頁面的情況。

  • vec的每個(gè)字節(jié)對(duì)應(yīng)指定區(qū)域內(nèi)的一個(gè)頁面笆豁,第一個(gè)字節(jié)對(duì)應(yīng)著第一個(gè)頁面郎汪,然后依次對(duì)應(yīng)。
  • vec必須足夠大來裝入(length - 1 + page_size)/page_size字節(jié)闯狱。如果頁面在物理內(nèi)存中煞赢,對(duì)應(yīng)字節(jié)的最低位是1,否則是0。其他的位目前還沒有定義哄孤。
  • 目前來說耕驰,這個(gè)系統(tǒng)調(diào)用只能用在以MAP_SHARED創(chuàng)建的基于文件的映射上。

投機(jī)性存儲(chǔ)分配策略

Linux使用投機(jī)性分配策略:當(dāng)一個(gè)進(jìn)程向內(nèi)核請(qǐng)求額外的內(nèi)存-如擴(kuò)大它的數(shù)據(jù)段录豺,或者創(chuàng)建一個(gè)新的存儲(chǔ)器映射-內(nèi)核作出了分配承諾但實(shí)際上并沒有分給進(jìn)程任何的物理存儲(chǔ)朦肘。

  • 僅當(dāng)進(jìn)程對(duì)新“分配到”的內(nèi)存區(qū)域作寫操作的時(shí)候,內(nèi)核才履行承諾双饥,分配一塊物理內(nèi)存媒抠。內(nèi)核逐頁完成上述工作,并在需要時(shí)進(jìn)行請(qǐng)求頁面調(diào)度和寫時(shí)復(fù)制咏花。

這樣處理有如下幾個(gè)優(yōu)點(diǎn)

  1. 延緩內(nèi)存分配允許內(nèi)核將大部分工作推遲到最后一刻(當(dāng)確實(shí)需要進(jìn)行分配時(shí))
  2. 由于請(qǐng)求是根據(jù)需求逐頁的分配趴生,只有真正需要物理內(nèi)存的時(shí)候才會(huì)消耗物理存儲(chǔ)
  3. 分配到的內(nèi)存可能比實(shí)際的物理內(nèi)存甚至比可用的交換空間多的多,這個(gè)特征叫超量使用昏翰。

超量使用和內(nèi)存耗盡

超量使用的好處:和在應(yīng)用請(qǐng)求頁面就分配物理存儲(chǔ)相比苍匆,在使用時(shí)刻才分配物理存儲(chǔ)的過量使用機(jī)制允許系統(tǒng)運(yùn)行更多,更大的應(yīng)用程序棚菊。
但是浸踩,如果系統(tǒng)中的進(jìn)程為滿足超量使用而申請(qǐng)的內(nèi)存大于物理內(nèi)存和交換空間之和,內(nèi)核只能殺死另一個(gè)進(jìn)程并釋放它的內(nèi)存统求,以此來滿足下一次的分配需求检碗。

  • 當(dāng)超量使用導(dǎo)致內(nèi)存不足以滿足一個(gè)請(qǐng)求時(shí),就發(fā)生了內(nèi)存耗盡(OOM)(out of memory)码邻。
  • 為了處理OOM折剃,內(nèi)核使用OOM終結(jié)者killer來挑選一個(gè)進(jìn)程,并終止它像屋。基于這個(gè)目的,內(nèi)核會(huì)嘗試選出一個(gè)最不重要且又占用很多內(nèi)存的進(jìn)程戈轿。
關(guān)閉超量使用:

內(nèi)核允許通過文件/proc/sys/vm/overcommit_memory關(guān)閉超量使用扶檐,和此功能相似的還有sysctl的vm.overcommit_memory參數(shù)凶杖。

  • 參數(shù)默認(rèn)值為0,告訴內(nèi)核執(zhí)行適度的超量使用策略
  • 參數(shù)值為1時(shí)胁艰,確認(rèn)所有的分配請(qǐng)求
  • 參數(shù)值為2時(shí)款筑,關(guān)閉所有的過量使用腾么,啟用嚴(yán)格審計(jì)(strict accounting)策略.
嚴(yán)格審計(jì)策略:

在嚴(yán)格審計(jì)模式中,承諾的內(nèi)存大小被嚴(yán)格限制在交換空間的大小加上可調(diào)比例的物理內(nèi)存大小解虱。

  • 比例默認(rèn)為50%攘须,因?yàn)槲锢韮?nèi)存還必須包含著內(nèi)核,頁表殴泰,系統(tǒng)保留頁于宙,鎖定頁等等東西悍汛。僅它的一部分能夠被交換和滿足承諾請(qǐng)求。
  • 比例可以在文件/proc/sys/vm/overcommit_ratio里面設(shè)置谱俭,作用和vm.overcommit_ratio的sysctl參數(shù)相似宵蛀。

使用嚴(yán)格審計(jì)策略時(shí)要非常小心!許多系統(tǒng)設(shè)計(jì)者認(rèn)為嚴(yán)格審計(jì)策略才是解決之道术陶,然而,應(yīng)用程序常常進(jìn)行一些不必要的梧宫、且只有使用超量使用才能滿足的分配請(qǐng)求,而允許這種行為也是設(shè)計(jì)虛擬內(nèi)存的主要?jiǎng)訖C(jī)之一疤坝。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末馆铁,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子历谍,更是在濱河造成了極大的恐慌,老刑警劉巖望侈,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件脱衙,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡捐韩,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門瞧预,熙熙樓的掌柜王于貴愁眉苦臉地迎上來仅政,“玉大人,你說我怎么就攤上這事滩愁≡送剩” “怎么了?”我有些...
    開封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵檀咙,是天一觀的道長璃诀。 經(jīng)常有香客問我,道長劣欢,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任校套,我火速辦了婚禮牧抵,結(jié)果婚禮上侨把,老公的妹妹穿的比我還像新娘妹孙。我一直安慰自己,他們只是感情好蠢正,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開白布嚣崭。 她就那樣靜靜地躺著,像睡著了一般有鹿。 火紅的嫁衣襯著肌膚如雪谎脯。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天娱俺,我揣著相機(jī)與錄音废麻,去河邊找鬼。 笑死油宜,一個(gè)胖子當(dāng)著我的面吹牛怜姿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播沧卢,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼但狭,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了立磁?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤宪摧,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后温圆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡岁歉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年锅移,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了饱搏。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡备绽,死狀恐怖鬓催,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情宇驾,我是刑警寧澤,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布塌西,位于F島的核電站筝尾,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏忿等。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一庵寞、第九天 我趴在偏房一處隱蔽的房頂上張望薛匪。 院中可真熱鬧,春花似錦古沥、人聲如沸瘸右。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至乞封,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間肃晚,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來泰國打工拧廊, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留悍缠,地道東北人耐量。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像趴拧,于是被迫代替她去往敵國和親山叮。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 操作系統(tǒng)對(duì)內(nèi)存的管理 沒有內(nèi)存抽象的年代 在早些的操作系統(tǒng)中脑又,并沒有引入內(nèi)存抽象的概念锐借。程序直接訪問和操作的都是物...
    Mr槑閱讀 16,699評(píng)論 3 24
  • 1 內(nèi)存尋址 1.1 物理地址、虛擬地址以及線性地址 物理地址: 物理內(nèi)存的內(nèi)存單元地址 虛擬地址: 程序員看到的...
    瘋狂小王子閱讀 2,813評(píng)論 3 21
  • 我是誰来颤? 我感覺我是活在自己的世界里奸例。
    杰克船長就是我閱讀 122評(píng)論 1 1
  • 你以后會(huì)遇見很多人 但你永遠(yuǎn)都不會(huì)見到我了 你可能會(huì)發(fā)現(xiàn)你身邊有那么一個(gè)人 有和我相似的一處 但你自習(xí)會(huì)發(fā)現(xiàn)就算有...
    sunninne閱讀 343評(píng)論 0 1
  • 艷陽依舊笑春風(fēng)洒擦,人約黃昏后鄙麦。 今年陽節(jié)時(shí)严沥,景與花依舊拷沸。 不見去年人薯演,淚滿春衫袖。 佳人已隨黃鶴去跨扮,新釀青梅為誰盛。...
    般若孤魚閱讀 275評(píng)論 0 1