早期計(jì)算機(jī)都是直接訪問物理內(nèi)存的,這樣想在內(nèi)存中同時(shí)運(yùn)行兩個(gè)程序是不可能的,想想為什么?
下面給出三種存儲模型:
第一種和第三種均不常用了,因?yàn)橛脩舫绦蛞坏┏霈F(xiàn)錯(cuò)誤,可能會銷毀OS,當(dāng)按上述方式裝載程序時(shí),新裝載的程序會覆蓋掉先前裝載的程序。唯一能并行的方法就是使用多線程,但是會共享信息,所以不可行。
后來提出內(nèi)存鍵的概念來區(qū)分在內(nèi)存中多道程序,此時(shí)內(nèi)存中可以裝載多道程序,但是一個(gè)程序可能因?yàn)閖mp指令跳轉(zhuǎn)到另一個(gè)程序從而發(fā)生程序崩潰。這都是因?yàn)槭褂昧私^對地址產(chǎn)生的問題,一種解決辦法是采用靜態(tài)重定位的方法,比如一個(gè)程序裝入到16000地址位,則程序中地址數(shù)都要加上16000這個(gè)常數(shù),雖然這種方法一般來講是可行的,但是無法辨別它是重定位的地址還是不是重定位的地址,來了一個(gè)訪問地址,那這個(gè)訪問地址加不加16000,而且該方法會減慢裝載速度。
一種存儲器的抽象:地址空間
要想多個(gè)程序同時(shí)處于內(nèi)存中就需要解決兩個(gè)問題:保護(hù)和重定向。我們希望每個(gè)程序都有自己獨(dú)立的一套地址空間。
一個(gè)簡單的方法是使用動態(tài)重定位,利用基址寄存器(存放程序開始地址)和界限寄存器(存放程序大?。?,當(dāng)指令讀或?qū)憯?shù)據(jù)字前,CPU硬件會將其發(fā)送到內(nèi)存總線前與基址寄存器中的值相加,并判斷相加后的指令是否越界。但是每次都要做加法運(yùn)算和比較運(yùn)算就會顯得很慢。
交換技術(shù)的出現(xiàn)
將所有進(jìn)程都裝載入內(nèi)存是不大可能的,一種策略是將空閑進(jìn)程存入磁盤,將需要使用的進(jìn)程整個(gè)裝入內(nèi)存;另一種策略是虛擬內(nèi)存
交換在內(nèi)存中產(chǎn)生了多個(gè)空閑區(qū),通過把所有內(nèi)存盡可能向下移動,有可能將這些小的內(nèi)存區(qū)合并為大的內(nèi)存區(qū),這稱為內(nèi)存壓縮,但通常不進(jìn)行該操作,因?yàn)榉浅:臅r(shí),而且OS需要準(zhǔn)確的按其需要的大小分配內(nèi)存。
但是如果數(shù)據(jù)段可以增長,例如,很多程序語言都允許從堆中動態(tài)分配內(nèi)存。所以我們可以為其預(yù)留一部分空間。
其中,堆棧存放私有變量和返回地址,向下增長。數(shù)據(jù)段作為堆使用供變量動態(tài)分配和釋放,向上增長。
空閑內(nèi)存區(qū)管理-位圖方法
內(nèi)存可能被劃分為小到幾個(gè)字,大到幾千字節(jié)的分配單元,每個(gè)分配單元對應(yīng)位圖中的一位,0表示空閑,1表示占用。在分配一個(gè)k個(gè)分配單元的進(jìn)程時(shí),需要在位圖中查找k個(gè)連續(xù)的分配單元進(jìn)行分配,這是非常耗時(shí)的。
空閑內(nèi)存區(qū)管理-鏈表
還有一個(gè)方法是維護(hù)一個(gè)記錄已分配的內(nèi)存段和空閑內(nèi)存段的鏈表,設(shè)當(dāng)X進(jìn)程結(jié)束后同時(shí)需要合并內(nèi)存。
當(dāng)然,這里有很多算法可以分配內(nèi)存,有首次適配法,下次適配法,最佳適配法(會生成更多的小的空閑區(qū),可以考慮最差適配法)等。
虛擬內(nèi)存
為了防止某程序過大,最開始采用覆蓋塊的方法,即手動切割程序成一個(gè)個(gè)小塊,但是怎么切割是個(gè)問題。于是這個(gè)問題干脆交給計(jì)算機(jī)去做,虛擬內(nèi)存就誕生了。其基本思想是:
每個(gè)程序都有自己的基本空間,這個(gè)空間被分成多個(gè)塊,每個(gè)塊稱作一頁和頁面。(注意:虛擬內(nèi)存就是利用磁盤空間來擴(kuò)大內(nèi)存,所以稱為虛擬)
放張圖就明白了:
這里,我們通過頁表(基址+偏移量)來管理頁面,也可以加上TLB(塊表),計(jì)算機(jī)組成原理的內(nèi)容吧。有時(shí),單個(gè)頁表是不夠表示頁面的,所以我們可以采用二級頁表或多級頁表,來看下面一張圖:
有頁面自然也有頁面置換算法,這些算法有最優(yōu)頁面置換算法,最近未使用置換算法,先進(jìn)先出置換算法等
在考慮如何交換時(shí),如果考慮換出單個(gè)進(jìn)程中最小生存時(shí)間的頁面稱為局部頁面置換算法,考慮換出整個(gè)內(nèi)存中最小生存時(shí)間的頁面稱為全局頁面置換算法。通常情況下全局算法較好。另一種途徑是為進(jìn)程平均分配頁面,剩余放入公共池里面。
我們也可以采用測試缺頁中斷率的方法。
同時(shí),我們也應(yīng)該選則合適的頁面大小,在共享方面,一般只讀的頁面可以作為共享頁面來減少內(nèi)存消耗。
共享庫
在靜態(tài)鏈接.o程序時(shí),會造成很大的內(nèi)存消耗,因?yàn)橐溄硬煌瑤煳募?,這些庫文件直接裝載至內(nèi)存。但是共享庫(又稱動態(tài)鏈接庫,DLL),只會裝載一小段能夠在運(yùn)行時(shí)綁定被調(diào)用函數(shù)的存根例程,即用什么函數(shù),才裝入對應(yīng)的頁面而不是整個(gè)文件裝入。當(dāng)然,如果其它程序裝載了該共享庫,則本程序就不需要裝載它了。
另外,如果DLL文件更新了,其并不需要重新編譯執(zhí)行,用戶只需要下載更新的DLL文件下次啟動時(shí)即可使用。
來看兩個(gè)進(jìn)程使用共享庫,需要用相對地址:
共享庫實(shí)際上是內(nèi)存映射文件的一個(gè)特例。
如何進(jìn)行缺頁中斷處理?
審核編輯:劉清
-
寄存器
+關(guān)注
關(guān)注
31文章
5253瀏覽量
119212 -
存儲器
+關(guān)注
關(guān)注
38文章
7366瀏覽量
163101 -
中斷處理
+關(guān)注
關(guān)注
0文章
94瀏覽量
10935
發(fā)布評論請先 登錄
相關(guān)推薦
評論