一、引子
1、計算兩方面的原因
2、內存管理機制
二、獨享內存空間的原理
1、會議室和物理內存的關系
和會議室一樣,內存都被分成一塊塊兒的,都編號了號,例如3F-10就是三樓十號會議室、內存頁有這樣一個地址。這個地址是實實在在的地址,通過這個地址我們就能夠定位到物理內存地址
2、會產生什么問題呢?
3F-10打開三個相同的程序,都執行到某一步,比方說,打開三個計算機器,用戶在這三個程序的界面、上分別輸入10、100、1000,如果內存中的這個位置只能保存一個數,
那應該保存那個呢?這不就沖突了嗎?
3、誰也不能直接訪問物理地址
每個項目的物理地址對於進程不可見,誰也不能直接訪問物理地址,操作系統會給進程分配一個虛擬地址。所有進程看到的這個地址都是一樣的,里面的內存都是從0開始編號
4、在程序里面,指令寫入的地址是虛擬地址
例如,位置我10M的內存區域,操作系統會提供一種機制,將不同的進程的虛擬地址和不同的物理地址映射起來
當程序要訪問虛擬地址的時候,由內核的數據結構轉換,轉換成不同的物理地址,這樣不同的進程運行的是時候,寫入的是不同的物理地址這樣就不會沖突了
三、規划地址空間
1、操作系統的內存管理,主要分為三個方面
於是,你看待了項目組的項目計划是這樣一個程序
#include <stdio.h> #include <stdlib.h> int max_length = 128; char * generate(int length){ int i; char * buffer = (char*) malloc (length+1); if (buffer == NULL) return NULL; for (i=0; i<length; i++){ buffer[i]=rand()%26+'a'; } buffer[length]='\0'; return buffer; } int main(int argc, char *argv[]) { int num; char * buffer; printf ("Input the string length : "); scanf ("%d", &num); if(num > max_length){ num = max_length; } buffer = generate(num); printf ("Random string is: %s\n",buffer); free (buffer); return 0; }
這個程序比較簡單,就是根據用戶輸入的整數來生成字符串,最長是128,由於字符串的長度不固定、因而不能提前知道,
需要動態地分配內存,是用malloc函數,當然用完了需要釋放內存,這就是要使用free函數
2、這個簡單的程序使用哪些內存的幾種方式
1、那些內存的幾種方式
2、內核部分還需要分配內存
3、上面的這些地址應該用虛擬地址訪問呢?還是應該用物理地址訪問呢?
真正能夠使用會議室物理地址的,只有會議室管理部門,
所有其他部分的行為涉及訪問會議室的,都需要統統使用虛擬地址、統統到會議室管理部門哪里轉換一道,才能進行統一的控制
用戶態的進程的進程使用虛擬地址,這點毫無你問,內核態的頁基本都是使用虛擬地址,
3、從“虛”的角度來看,這一大片連續的內存空間都是我的了
1、一大片連續的內存
2、這個么大的空間都存些什么內容呀
4、用戶空間存放內容詳解
5、不同視覺
雖然內核代碼權限很大,但是能夠使用的虛擬地址范圍也只能在內核空間,也即內核代碼訪問內核數據結構,只能用30號到39號這些編程,不能用0-29號,
因為這些事被金額呈空間占用的,而且、進程有很多個、你現在在內核,但是你不知道當前指的0號是那進程的0號
在內核里面也會有內核的代碼,同樣有 Text Segment、Data Segment 和BSS Segment,別忘了咱們講內核啟動的時候,內核代碼也是 ELF 格式的。
四、總結時刻
通過這一節,你應該知道,一個內存管理系統至少應該做三件事情:
第一,虛擬內存空間的管理,每個進程看到的是獨立的、互不干擾的虛擬地址空間;
第二,物理內存的管理,物理內存地址只有內存管理模塊能夠使用;
第三,內存映射,需要將虛擬內存和物理內存映射、關聯起來