【Linux】虚拟地址空间
文章目錄
- 1. 物理地址和虛擬地址定義
- 2. 虛擬地址空間分布
- 2.1 內核空間
- 2.2 棧(stack)
- 2.3 堆(heap)
- 2.4 BSS段
- 2.5 數據段(Data)
- 2.6 代碼段(text)
- 2.7 保留區
- 3. 分段式存儲
- 3.1 分段式存儲定義
- 3.2 分段式存儲示例
- 3.3 分段式存儲優缺點
- 4. 分頁式存儲
- 4.1 分頁式存儲定義
- 4.2 分頁式存儲示例
- 4.3 分頁式存儲優缺點
1. 物理地址和虛擬地址定義
物理地址 (physical address): 放在尋址總線上的地址。放在尋址總線上,如果是讀,電路根據這個地址每位的值就將相應地址的 物理內存中的數據放到 數據總線中傳輸。如果是寫,電路根據這個地址每位的值就在相應地址的 物理內存中放入 數據總線上的內容。 物理內存是以 字節(8位)為單位 編址的。
虛擬地址 (virtual address): CPU啟動 保護模式后,程序運行在虛擬 地址空間中。注意,并不是所有的“程序”都是運行在虛擬地址中。CPU在啟動的時候是運行在實模式的,Bootloader以及內核在初始化頁表之前并不使用虛擬地址,而是直接使用物理地址的。
2. 虛擬地址空間分布
2.1 內核空間
內核總是駐留在內存中,是操作系統的一部分。內核空間為內核保留,不允許應用程序讀寫該區域的內容或直接調用內核代碼定義的函數。
2.2 棧(stack)
-
棧是由高地址向低地址擴展的連續內存,棧的大小一般為 2M 或者 10M。
-
棧內存是由系統分配,系統釋放的,以函數為單位進行棧內存分配,函數棧幀,局部變量,形參變量等都存放在棧內存上。
-
棧的內存分配釋放速度快效率高,內存都是連續的。
2.3 堆(heap)
-
堆是由低地址向高地址擴展的非連續內存,堆的大小影響的因素比較多,和系統虛擬內存的大小有關系。
-
堆內存是由用戶自己分配的,C 語言用 malloc/free進行分配釋放,C++用 new/delete 進行分配釋放,由于堆需要用戶自己管理,因此堆內存很容易造成內存泄露,而棧內存不會。
-
堆內存的分配釋放相對于棧來說效率低一些,內存不一定連續,容易產生內存碎片,但是靈活性高。
2.4 BSS段
BSS(Block Started by Symbol)段中通常存放程序中以下內容
-
未初始化的全局變量和靜態局部變量
-
初始值為0的全局變量和靜態局部變量(依賴于編譯器實現)
-
未定義且初值不為0的符號(該初值即common block的大小)
2.5 數據段(Data)
數據段通常用于存放程序中已初始化且初值不為0的全局變量和靜態局部變量。數據段屬于靜態內存分配(靜態存儲區),可讀可寫。
數據段保存在目標文件中(在嵌入式系統里一般固化在鏡像文件中),其內容由程序初始化。例如,對于全局變量int gVar = 10,必須在目標文件數據段中保存10這個數據,然后在程序加載時復制到相應的內存。
2.6 代碼段(text)
代碼段也稱正文段或文本段,通常用于存放程序執行代碼(即CPU執行的機器指令)。
2.7 保留區
位于虛擬地址空間的最低部分,未賦予物理地址。任何對它的引用都是非法的,用于捕捉使用空指針和小整型值指針引用內存的異常情況。
3. 分段式存儲
3.1 分段式存儲定義
段式管理(segmentation),是指把一個程序分成若干個段(segment)進行存儲,每個段都是一個邏輯實體(logical entity),程序員需要知道并使用它。它的產生是與程序的模塊化直接有關的。段式管理是通過段表進行的,它包括段號或段名、段起點、裝入位、段的長度等。此外還需要主存占用區域表、主存可用區域表。
3.2 分段式存儲示例
假設有兩個進程 A 和 B ,進程 A 所需內存大小為 10M ,其虛擬地址空間分布在 0x00000000 到 0x00A00000 ,進程 B 所需內存為 100M ,其虛擬地址空間分布為 0x00000000 到 0x06400000 。那么按照分段的映射方法,進程 A 在物理內存上映射區域為 0x00100000 到 0x00B00000 ,,進程 B 在物理內存上映射區域為 0x00C00000 到 0x07000000 。于是進程 A 和進程 B 分別被映射到了不同的內存區間,彼此互不重疊,實現了地址隔離。從應用程序的角度看來,進程 A 的地址空間就是分布在 0x00000000 到 0x00A00000 ,在做開發時,開發人員只需訪問這段區間上的地址即可。應用程序并不關心進程 A 究竟被映射到物理內存的那塊區域上了,所以程序的運行地址也就是相當于說是確定的了。
3.3 分段式存儲優缺點
優點
在段式存儲管理中,每個段地址的說明為兩個量:一個段名和一個位移。在段內,是連續完整存放的。而在段與段之間是不一定連續編址的。段名和位移構成了一種二維編址。 段式管理是不連續分配內存技術中的一種。其最大特點在于他按照用戶觀點,即按程序段、數據段等有明確邏輯含義的“段”,分配內存空間。克服了頁式的、硬性的、非邏輯劃分給保護和共享與支態伸縮帶來的不自然性。 段的最大好處是可以充分實現共享和保護,便于動態申請內存,管理和使用統一化,便于動態鏈接。
缺點
(1) 有內存碎片產生問題。
(2) 在分段的映射方法中,每次換入換出內存的都是整個程序, 這樣會造成大量的磁盤訪問操作,導致效率低下。
4. 分頁式存儲
4.1 分頁式存儲定義
將各進程的虛擬空間劃分成若干個長度相等的頁(page),頁式管理把內存空間按頁的大小劃分成片或者頁面(page frame),然后把頁式虛擬地址與內存地址建立一一對應頁表,并用相應的硬件地址變換機構,來解決離散地址變換問題。頁式管理采用請求調頁或預調頁技術實現了內外存存儲器的統一管理。
4.2 分頁式存儲示例
一個可執行文件 (PE 文件 ) 其實就是一些編譯鏈接好的數據和指令的集合,它也會被分成很多頁,在 PE 文件執行的過程中,它往內存中裝載的單位就是頁。在 PE 文件的第一頁包含了 PE 文件頭和段表等信息,進程根據文件頭和段表等信息,將 PE 文件中所有的段一一映射到虛擬地址空間中相應的頁 (PE 文件中的段的長度都是頁長的整數倍 ) 。這時 PE 文件的真正指令和數據還沒有被裝入內存中,操作系統只是根據 PE 文件的頭部等信息建立了 PE 文件和進程虛擬地址空間中頁的映射關系而已。當 CPU 要訪問程序中用到的某個虛擬地址時,當 CPU 發現該地址并沒有相相關聯的物理地址時, CPU 認為該虛擬地址所在的頁面是個空頁面, CPU 會認為這是個頁錯誤 (Page Fault) , CPU 也就知道了操作系統還未給該 PE 頁面分配內存, CPU 會將控制權交還給操作系統。操作系統于是為該 PE 頁面在物理空間中分配一個頁面,然后再將這個物理頁面與虛擬空間中的虛擬頁面映射起來,然后將控制權再還給進程,進程從剛才發生頁錯誤的位置重新開始執行。由于此時已為 PE 文件的那個頁面分配了內存,所以就不會發生頁錯誤了。隨著程序的執行,頁錯誤會不斷地產生,操作系統也會為進程分配相應的物理頁面來滿足進程執行的需求。
4.3 分頁式存儲優缺點
優點
(1) 由于它不要求作業或進程的程序段和數據在內存中連續存放,從而有效地解決了碎片問題。
(2) 動態頁式管理提供了內存和外存統一管理的虛存實現方式,使用戶可以利用的存儲空間大大增加。這既提高了主存的利用率,又有利于組織多道程序執行。
缺點
(1) 要求有相應的硬件支持。例如地址變換機構,缺頁中斷的產生和選擇淘汰頁面等都要求有相應的硬件支持。這增加了機器成本。
(2) 增加了系統開銷,例如缺頁中斷處理機。
(3) 請求調頁的算法如選擇不當,有可能產生抖動現象。
(4) 雖然消除了碎片,但每個作業或進程的最后一頁內總有一部分空間得不到利用果頁面較大,則這一部分的損失仍然較大。
總結
以上是生活随笔為你收集整理的【Linux】虚拟地址空间的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Linux】Makefile文件
- 下一篇: 智能指针——auto_ptr