乙個linux程序的虛擬位址空間分布如下圖所示,分為使用者空間和核心空間,對於乙個32位作業系統來說,4gb的空間分成兩部分,低位址的0~3g給使用者空間,高位址的3g~4g給核心空間
2.1 唯讀資料段(.rodata,又叫做常量資料段)
存放唯讀資料(字串常量和const修飾的全域性變數);const修飾的全域性變數是存放在常量段的,但是使用const修飾的區域性變數不存放在常量段,存放在棧段;為了提高空間的利用率,有些系統中.rodata段是多個程序共享的;程式載入執行時,.rodata和.text通常合併到乙個段(text segment)中,作業系統將這個段唯讀保護起來,防止意外的改寫
2.2 **段(.text)
程式**在記憶體中的對映,存放函式體的二進位制**;
2.3 已初始化過的資料段(.data)
資料段儲存在源**中已經初始化的靜態變數的內容。資料段不是匿名的,它映**一部分的程式二進位制映象,也就是源**中指定了初始值的靜態變數。
2.4 未初始化過的資料(.bss)
bss儲存的是未被初始化的靜態變數內容,他們沒有直接在程式的原始碼中被賦值。bss記憶體區域是匿名的,它不對映到任何檔案。.data和.bss在程式載入時合併到乙個段(data segment)中,這個段是可讀可寫的。
2.5 堆(heap)
堆用於執行時記憶體分配;但不同於棧的是,堆用於儲存那些生存期與函式呼叫無關的資料。大部分語言都提供了堆管理功能。在c語言中,堆分配的介面是malloc()函式。如果堆中有足夠的空間來滿足記憶體請求,它就不需要核心參與,否則,堆會被擴大,通過brk()系統呼叫來分配請求所需的記憶體塊。
2.6 記憶體對映段
常被用來載入共享庫(動態庫);記憶體對映:將虛擬記憶體空間與磁碟上的檔案關聯起來,這個過程叫記憶體對映
2.7 棧(stack)
棧用於儲存函式引數和區域性變數。在程式中呼叫乙個方法或函式會將乙個新的棧幀(stack frame)壓入到棧中,這個棧幀會在函式返回時被清理掉。棧中資料遵守先進先出的原則,有乙個指標指向棧的頂端用來追蹤棧中的內容,可以再較短的時間內完成資料壓棧和退棧(popping)。程序中的每乙個執行緒都有屬於自己的棧。
【當通過不斷向棧中壓入資料,超出其容量就會耗盡棧所對應的記憶體區域,這將觸發乙個頁故障(page fault),而被linux的expand_stack()處理,它會呼叫acct_stack_growth()來檢查是否還有合適的地方用於棧的增長。如果棧的大小低於限制的大小rlimit_stack(通常為8mb),那麼一般情況下棧會被加長,程式繼續執行,感覺不到發生了什麼事情。這是一種將棧擴充套件到所需大小的常規機制。然而,如果達到了最大棧空間的大小,就會棧溢位(stack overflow),程式收到乙個段錯誤的提示。動態棧增長是唯一一種訪問未對映記憶體區域而被允許的情形,其他任何對未對映記憶體區域的訪問都會觸發頁錯誤,從而導致段錯誤。一些被對映的區域是唯讀的,因此企圖寫這些區域也會導致段錯誤】
** 棧和堆的區別**:
3.1 核心**段
存放核心的**和資料,所有程序的核心**段都對映到同樣的物理記憶體,並在記憶體中持續存在。
2.2 與程序有關的資料結構段
存放程序各自的pcb等,並對映到不同的物理記憶體;
Linux程序位址空間
我們知道,在32位機器上linux 作業系統中的程序的位址空間大小是4g,其中0 3g是使用者空間,3g 4g是核心空間。其實,這個4g的位址空間是不存在的,也就是我們所說的虛擬記憶體空間。c程式一直由下列幾部分組成 a.正文段。這是由cpu執行的機器指令部分。通常,正文段是可共享的,所以即使是經常...
Linux 程序位址空間 簡介
程序虛擬位址空間是linux的乙個重要抽象,系統為每乙個執行的linux程序提供了4gb的虛擬位址空間,程序之間不會相互干擾,僅能訪問自己的虛擬位址空間位址。linux程序的虛擬位址空間分為user和kernel兩個部分,0 3g是為程序的user位址空間,3g 4g為kernel位址空間。此外程序...
程序位址空間
這篇文章應該不能說是原創的,這裡的記錄都是我通過閱讀整理來的,並沒有太多的自己的想法。資料 現代作業系統 之所以去了解位址空間也是因為在學習dll的時候看到要將dll對映到程式的位址空間,不甚明了所以去查詢相關的資料。位址空間其實很好理解 當然針對早期的機器 早期的機器是沒有ram,rom,cach...