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

單片機的程序在內(nèi)存和FLASH中應(yīng)該如何進行空間分配

評論