目錄
一、虛擬地址空間
1.虛擬地址空間的定義
2.虛擬地址空間的布局
二、內存壁壘
? ? ? ? 1.內存壁壘的定義?編輯
2.段錯誤
三、內存映射的建立與解除
? ? ? ? (1)mmap
? ? ? ? (2)munmap
(3)堆內存的分配和釋放
1.sbrk
2.brk
????????我們先來思考一個問題:你寫出的程序經過編譯之后得到a.out是如何跑起來的呢?
? ? ? ? a.out文件是二進制指令的集合。其內容經過了操作系統的管理調度被加載到了物理內存中,CPU再從物理內存中讀取指令,并且執行,這樣我們的程序就跑起來啦!
一、虛擬地址空間
1.虛擬地址空間的定義
? ? ? ??
????????這段文字告訴了我們:我們看到的地址是假的!是操作系統給我們看到的表象,我們借助這個表象的地址+操作系統存下的映射關系就能找到相應的物理內存,從而進行數據的訪問了。
? ? ? ? 那么操作系統為什么要維護這樣一個映射關系表呢?而不給我們實際的物理地址?
其實在計算機剛剛誕生的時候(還沒有操作系統),人們就是這樣做的,但是這樣會有許許多多的麻煩事,人們要不斷的計算所使用內存的大小,從而規劃下一步在哪個地方使用內存,但是一旦操作不當就會導致內存泄漏或者程序崩潰。
? ? ? ? 于是人們便開發了操作系統這樣的一個東西來幫助我們合理使用內存。而操作系統自己用了一個虛擬內存的東西來映射實際的物理內存,從而知道哪一塊空間被使用了,哪一塊空間沒有被使用,自此我們對內存的操作大部分都交給了操作系統來處理,于是人力資源得到了極大的程度的解放。
32位:
? ? ? ? (1)對于32位操作系統而言,每個進程都有4G大小的虛擬地址空間。
? ? ? ? (2)所謂的地址空間就是一個地址范圍,表示程序的尋址能力(但是并不意味著一定用到了4G大小的物理內存)我們所看到的虛擬地址都是在4G的這個范圍內的
????????(3)對于32位操作系統,其虛擬地址空間范圍是0X0000 0000到0XFFFF FFFF也就是4G
? ? ? ? (4)其中的0到3G-1范圍歸用戶使用,稱為用戶地址空間;3G到4G-1的范圍歸內核使用,稱為內核地址空間。
64位:
? ? ? ? (1)對于64位操作系統而言,目前的程序還沒有那么大的內存需求,所以不支持完全的64位虛擬地址
? ? ? ? (2)64位操作系統上,其用戶的地址空間是0X0000 0000 0000 0000到0X0000 FFFF FFFF FFFF
? ? ? ? (3)其內核的地址空間是0XFFFF 0000 0000 0000到0XFFFF FFFF FFFF FFFF
? ? ? ? (4)內核地址空間和用戶地址空間之間的是不規范地址空間,不允許使用
? ? ? ? (5)用戶地址空間的代碼不能直接訪問內核空間的代碼和數據,但是可以通過系統調用進入內核,間接與系統內核交互
2.虛擬地址空間的布局
二、內存壁壘
? ? ? ? 1.內存壁壘的定義
????????從上面一段話中,我們可以看到:每一個進程中,只有內核空間的虛擬地址是一樣的,別的用戶地址空間部分都是各自獨立的(可能在兩個進程中,虛擬地址的值都是一樣的,但是映射在物理內存中卻有差別)
? ? ? ? 且內核的代碼和數據只能通過系統調用來訪問!!!
2.段錯誤
????????
????????第一種情況是:對沒有映射到物理內存的虛擬內存進行了訪問,但是操作系統沒有記錄這個虛擬地址,所以就成了一個野指針類似的虛擬地址。
? ? ? ? 第二種情況是:在只讀內存區域進行了寫操作(比如在常量代碼段進行修改)
三、內存映射的建立與解除
? ? ? ? (1)mmap
????????一般情況下,我們第一個參數start都給的是NULL讓系統自己來決定細虛擬地址;
????????length要求是按頁圓整(即4096的整數倍個字節);
????????而prot必須在PROT_READ和PROT_WRITE以及PROT_EXEC和PROT_NONE中選擇一個,作為我們映射區的操作權限;
????????最后,flags是映射標志,我們這里因為沒有涉及到文件,所以是將虛擬內存映射到物理內存中,所以要選擇MAP_ANONYMOUS(注意這里的flags都是可以多種選擇的,比如我們可以用MAP_PRIVATE|MAP_ANONYMOUS讓他既是匿名映射又是映射到緩沖區中)
? ? ? ? fd是文件描述符,我們在后續講到文件系統的時候再說