操作系統(tǒng) 內(nèi)存管理

在考慮操作系統(tǒng)如何管理內(nèi)存之前掀淘,你先要知道:

  1. 程序是存在硬盤中的二進制文件烙荷,需要運行時會經(jīng)過CPU調(diào)度程序?qū)⑵鋍opy到內(nèi)存后成為進程
  • cpu可以直接訪問的大容量存儲只有內(nèi)存

  • 內(nèi)存管理的目的在于快速訪問內(nèi)存钱磅,第二在于內(nèi)存的安全訪問(各個進程間的內(nèi)存不可以隨意互相訪問)

注:程序是如何形成的

源程序經(jīng)過編譯器變成一個個模塊,這些模塊和經(jīng)過 鏈接器式撼,經(jīng)過加載模塊之后,再和系統(tǒng)庫一起經(jīng)過加載器加載告匠,最后在和動態(tài)鏈接的系統(tǒng)庫鏈接成為二進制程序

這期間有

動態(tài)加載技術(shù):不是將所有模塊一起加載到內(nèi)存中戈抄,而是按需加載,一個子程序只有當被其他子程序調(diào)用時才會被加載后专。提高了空間利用率

動態(tài)鏈接于共享庫:不同程序程序中很多功能其實都是相似的划鸽,而這些重復(fù)的功能模塊加載到內(nèi)存中無疑要
占用很大一部分物理內(nèi)存,于是我們把他們抽調(diào)出來戚哎,形成專用的共享庫裸诽。這樣不僅節(jié)省空間,更利于程序的更新

對于1: 根據(jù)內(nèi)存管理方案型凳,調(diào)入內(nèi)存中的進程在執(zhí)行時可以再內(nèi)存和磁盤間移動丈冬,等待調(diào)入內(nèi)存的進程形成一個輸入隊列

編譯器將符號地址綁定在了可重新定位的的地址(比如本模塊開始第14字節(jié))。鏈接程序或者加載程序再將這些可重定位的地址綁定位絕對地址(如74104)甘畅。每次綁定都是一個地址空間到另一個的映射

對于2 :CPU只能訪問內(nèi)存殷蛇,那么CPU發(fā)出的指令肯定都是基于內(nèi)存來編址的实夹。再考慮到,編程時總不可能指定實際內(nèi)存地址粒梦,這樣在的程序經(jīng)不起環(huán)境改變的考驗。
為了解決這樣的問題荸实,計算機采用了 邏輯地址 和 * 物理地址* 的設(shè)計:

cpu 產(chǎn)生的地址通常稱為邏輯地址匀们,而內(nèi)存單元所看到的地址通常稱為物理地址

可以這么想:邏輯地址就是操作系統(tǒng)用戶編程時無視不同機器物理地址的不同所設(shè)置的屏蔽,編程時不必考慮實際的物理內(nèi)存分配是很happy的...... 實際使用時會有內(nèi)存管理單元來把邏輯內(nèi)存映射為物理內(nèi)存

對于3 使用高速緩存catch可以增加訪存速度准给,增加基地址和界限地址寄存器泄朴,一個可用的方案就是邏輯地址+基地址寄存器地址,如果這個值不大于界限地址寄存器里的值露氮,那么這就可作為物理地址祖灰,而基地址寄存器和界限地址寄存器是由操作系統(tǒng)初始化和指定的,用戶沒有權(quán)限去操作畔规。這樣就保證了第二點

只要我們使用內(nèi)存局扶,我們就必然會面臨一個問題,內(nèi)存不夠用HāH琛!

這一點是很頭疼的莫绣,尤其是對于大型單機游戲來說畴蒲,這就需要我們用到另一個技術(shù)交換

交換就是在某個進程在不被使用的時候被交換到備份存儲中(一般是磁盤)這樣的過程叫滾出.....
需要他的時候再將它加載回來..這樣的過程叫...滾入....而且這樣的交換總是在相同的物理空間上,通俗的講就是從哪滾出的对室,再從哪滾入...

這樣的交換其實對效率沒有什么良好的幫助模燥,現(xiàn)在UNIX系統(tǒng)就是只要當內(nèi)存被填滿了才會啟動交換,平時是不會的

內(nèi)存必須容納操作系統(tǒng)和用戶的一系列進程掩宜,那么怎么才能有效的分配這一濟源呢蔫骂?

這里將提到常用的幾個方法

連續(xù)內(nèi)存分配

  • 多分區(qū)方法,將內(nèi)存分配成許多個大小相同的模塊锭亏,這種不考慮具體使用情況而異想天開的平均分配主義已經(jīng)不再使用了纠吴,因為這樣造成的浪費是巨大的..其一,進程的大小可能相差甚遠慧瘤,單位塊大小不好決定啊戴已。

  • 可變分區(qū):操作系統(tǒng)有一個表,用于記錄哪些內(nèi)存可用和哪些內(nèi)存已被占用锅减√抢埽可用內(nèi)存稱為孔,進程進來之后怔匣,內(nèi)存管理單元會幫其找到合適的孔(注1)握联,如果孔還有剩余桦沉,那么這個孔..還是孔,變成了小孔而已...
    當內(nèi)存被釋放時金闽,被釋放出的內(nèi)存重新成為孔..如果相鄰的內(nèi)存也是孔..那么纯露,這兩個孔就合體成為大孔..

注1:這樣的策略有最先適應(yīng),最佳適應(yīng)代芜,最差適應(yīng):

最先適應(yīng)埠褪,找到的一個適應(yīng)的孔
最佳適應(yīng);遍歷所有孔挤庇,找到滿足要求的最小孔
最差適應(yīng):遍歷所有孔钞速,分配最大孔
效率上看 最先》最佳》最差

這兩種方案都是常用的連續(xù)內(nèi)存分配方法,但是連續(xù)內(nèi)存分配必然會面臨一個問題:碎片問題嫡秕,每次分配內(nèi)存渴语,都有部分內(nèi)存沒有被真正使用,如多分區(qū)方法中一個分區(qū)大小為4KB 昆咽,而一個內(nèi)存是 4KB +1B這樣的狀態(tài)驾凶,這種情況下必須要給這個進程分配兩個內(nèi)存塊,但是第二個內(nèi)存塊明顯存在內(nèi)存的浪費潮改!這樣的碎片稱為內(nèi)部碎片 狭郑,而可變分區(qū)方案中,總有一些孔被很小汇在,沒有進程能被分配進去翰萨,這樣的內(nèi)存稱為:內(nèi)部碎片

那么這樣的碎片多嗎?...有這樣的一個原則--50%規(guī)則糕殉,有N的內(nèi)存空間將有0.5N的外部碎片..
解決的方法有

緊縮:把所有隨便集中亩鬼,但是這樣先不考慮 重定位的問題。這樣的開銷也是不可接受的
使用非連續(xù)的內(nèi)存分配

非連續(xù)內(nèi)存分配

分頁:將物理內(nèi)存分為大小固定的塊阿蝶,稱為幀( frame)邏輯地址分為同樣大小的塊陨亡,稱為頁(page)

由CPU生成的地址分為兩部分浪慌,頁號和頁偏移谣沸,頁號作為頁表的索引苛蒲,頁表內(nèi)存入每頁所在物理地址的基地址,基地址于頁偏移組合就成為了物理地址筑煮,這樣就可以避免外部碎片的問題(但內(nèi)存碎片仍然存在)

當程序需要執(zhí)行的時候辛蚊,他將檢查該進程的大小,進程的每一頁都需要一幀真仲,如果幀夠袋马,那么分配,并將幀號放入進程的頁表中

操作系統(tǒng)管理內(nèi)存秸应,所以它必須知道哪些幀已經(jīng)使用了虑凛,哪些沒被使用碑宴。這個信息存儲在幀表中

硬件支持:絕大多數(shù)操作系統(tǒng)為每一個進程維護一個頁表。頁表的指針與其他信息一起存入進程控制塊中桑谍。
訪存操作可能是最頻繁的操作了延柠,所以效率是十分關(guān)鍵的÷嗯基于效率考慮捕仔,頁表最好不要存在一般內(nèi)存中,這樣會使得一次訪存操作變成消耗兩次訪存的時間盈罐,效率就很低了。對此闪唆,我們可以采用專用高速寄存器來存儲頁表盅粪,對于頁表比較小的情況下這樣做是可以的。但現(xiàn)代操作系統(tǒng)頁表通常很大...之后采取的方法是將頁表存入內(nèi)存中悄蕾,然后將其基地址存入寄存器票顾,之后按照偏移地址來存...這樣會很慢...于是我們就采用了比較小但很快的專用緩存來存頁表 ,稱為轉(zhuǎn)換表緩沖區(qū)

TLB相當于一個哈希表帆调,用KEY(頁號)可以快速找到VALUE(幀號)奠骄,找到了之后訪存,找不到就去內(nèi)存中找真正的頁表番刊,找到之后用一定的算法(最近最少使用)替換到TLB中方便下次尋找

保護: 通過頁表中的保護位來做含鳞,確定進程對其是可讀還是可寫的

采用這樣的結(jié)構(gòu),還可以共享某些頁芹务,這樣又節(jié)省了內(nèi)存

  • 頁表結(jié)構(gòu)
    • 層次頁表
      現(xiàn)代操作系統(tǒng)中的邏輯空間地址十分大.后果是頁表也十分大蝉绷,怎么樣在內(nèi)存中存儲頁表呢?一種方法是兩級分頁算法枣抱,將頁再分頁熔吗,對于64位的系統(tǒng)甚至可以再分頁

    • 哈希頁表
      每個元素有三個域 1. 虛擬頁碼 2. 所映射的幀號 3. 指向鏈表中下一個元素的指針

虛擬地址中的虛擬頁號轉(zhuǎn)換到哈希表中,用虛擬頁號與鏈表中的每一個元素的第一個域相比較佳晶。如果匹配桅狠,那么相應(yīng)的幀號就用來形成物理地址;如果不匹配轿秧,那么就去對鏈表中下一個節(jié)點進行比較

* 反向頁表
分段

這是為了方便用戶角度來看的中跌,將一維的地址空間二維化,原先是這個程序的第XX字節(jié)淤刃,這樣的一維查找晒他,而分段使得 這個程序 XX段的 YY字節(jié) 成為二維查找

當然這樣的方式需要特別的結(jié)構(gòu)..段表的支持

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市逸贾,隨后出現(xiàn)的幾起案子陨仅,更是在濱河造成了極大的恐慌津滞,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,948評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件灼伤,死亡現(xiàn)場離奇詭異触徐,居然都是意外死亡,警方通過查閱死者的電腦和手機狐赡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評論 3 385
  • 文/潘曉璐 我一進店門撞鹉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人颖侄,你說我怎么就攤上這事鸟雏。” “怎么了览祖?”我有些...
    開封第一講書人閱讀 157,490評論 0 348
  • 文/不壞的土叔 我叫張陵孝鹊,是天一觀的道長。 經(jīng)常有香客問我展蒂,道長又活,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,521評論 1 284
  • 正文 為了忘掉前任锰悼,我火速辦了婚禮柳骄,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘箕般。我一直安慰自己耐薯,他們只是感情好,可當我...
    茶點故事閱讀 65,627評論 6 386
  • 文/花漫 我一把揭開白布隘世。 她就那樣靜靜地躺著可柿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪丙者。 梳的紋絲不亂的頭發(fā)上复斥,一...
    開封第一講書人閱讀 49,842評論 1 290
  • 那天,我揣著相機與錄音械媒,去河邊找鬼目锭。 笑死,一個胖子當著我的面吹牛纷捞,可吹牛的內(nèi)容都是我干的痢虹。 我是一名探鬼主播,決...
    沈念sama閱讀 38,997評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼主儡,長吁一口氣:“原來是場噩夢啊……” “哼奖唯!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起糜值,我...
    開封第一講書人閱讀 37,741評論 0 268
  • 序言:老撾萬榮一對情侶失蹤丰捷,失蹤者是張志新(化名)和其女友劉穎坯墨,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體病往,經(jīng)...
    沈念sama閱讀 44,203評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡捣染,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,534評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了停巷。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片耍攘。...
    茶點故事閱讀 38,673評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖畔勤,靈堂內(nèi)的尸體忽然破棺而出蕾各,到底是詐尸還是另有隱情,我是刑警寧澤庆揪,帶...
    沈念sama閱讀 34,339評論 4 330
  • 正文 年R本政府宣布示损,位于F島的核電站,受9級特大地震影響嚷硫,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜始鱼,卻給世界環(huán)境...
    茶點故事閱讀 39,955評論 3 313
  • 文/蒙蒙 一仔掸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧医清,春花似錦起暮、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至柏腻,卻和暖如春纸厉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背五嫂。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評論 1 266
  • 我被黑心中介騙來泰國打工颗品, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人沃缘。 一個月前我還...
    沈念sama閱讀 46,394評論 2 360
  • 正文 我出身青樓躯枢,卻偏偏與公主長得像,于是被迫代替她去往敵國和親槐臀。 傳聞我的和親對象是個殘疾皇子锄蹂,可洞房花燭夜當晚...
    茶點故事閱讀 43,562評論 2 349

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