最近在看李先靜老師的《系統程式設計師成長計畫》的書,***也在他的部落格中寫了有關內容:當然這裡所說的linux記憶體模型也是***部落格中提到。這裡自己再寫出來,不是說自己寫的比***好,而是為了增加自己的理解,習慣性的將東西寫出來。
在說linux中記憶體模型之前,我們先了解幾個資料存放的概念:
1. .bss段
bss(block started by symbol)通常是指用來存放程式中未初始化的全域性變數和靜態變數的一塊記憶體區域。特點是:可讀寫的,在程式執行之前bss段會自動清0。所以,未初始的全域性變數在程式執行之前已經成0了。不過不是所有的平台都會把為初始換的靜態變數自動清0的,所以手動的將未初始化的靜態變數清零是乙個比較好的習慣。
2. .data段
這個是和.bss段相對應的,它是用來存放初始化的全域性變數和靜態變數。當然和.bss段一樣,他們都是全域性變數,在整個程式的執行週期內,它們都是一直存在的。
3. .rodata段
它是read only data的簡稱,也就是它是用來存放常量資料的。關於rodata型別的資料,需要注意一下幾點:(***部落格中有說)
(1)常量不一定存放在rodata段中,有的立即數直接和指令編碼一起,存放在**段(.text)中
(2)對於字串常量,編譯器會自動去掉重複的字串,保證乙個字串在乙個可執行檔案(exe/so,so是共享庫的檔案型別)中只存在乙個副本。
(3)在有的嵌入式系統中, rodata存放在rom裡,執行時直接讀取,無需載入到ram中。
(4)在嵌入式linux系統中,也可以通過一種叫做xip(execute in place,即晶元內執行,指應用程式可以直接在flash快閃儲存器內執行,不必再把**讀到系統ram中。flash內執行是指nor flash 不需要初始化,可以直接在flash內執行**。但往往只執行部分**,比如初始化ram。)的技術直接讀取常量資料,而無需載入到ram中。
(5)常量是不能修改的,修改常量在linux下會出現段錯誤(segment fault)。
(6)rodata是在多個程序間共享的,這樣可以提高執行空間利用率。
4. **段(.text)
**段可以存放**和部分整數常量,它是可以執行的,它的特性和rodata比較類似。
5. 棧(stack)
棧是一種常見的資料結構,它可以實現一些比較好的功能。比如它可以解析遞迴的過程,可以利用棧進行非遞迴的計算。這裡我們說的不是資料結構,而是一種記憶體儲存資料的方式。它是向下生長的,這是因為不同平台對棧的最大值做了規定,在cpu中通過ess(棧暫存器),ebp(基址暫存器),esp(棧頂暫存器)來操作棧的。需要注意的是,不同執行緒或程序都有自己私有的棧,這些棧在程式退出的時候會自動銷毀。
6. 堆(heap)
堆是一種靈活的記憶體,它的生命週期完全由使用者控制。它和棧不同的地方包括:它需要使用者進行手動的分配和收回,它是向上生長的。標準c提供了一下幾個函式來使用堆記憶體。
malloc :用來分配一塊指定大小的記憶體
realloc :用來重新分配一塊記憶體
calloc :用來分配一塊指定大小的記憶體,並進行清0的初始化
free :**不再使用的堆記憶體
alloc : alloc函式不同於其他分配堆記憶體函式的是:函式afree和函式alloc是「不完善」的,是因為對afree函式的呼叫次序必須與呼叫alloc函式的次序相反。換句話說,alloc與afree以棧的方式(即後進先出的列表)進行儲存空間的管理
下面是linux記憶體模型,這是「偷」***部落格中的,
linux的記憶體模型,一般為:位址
作用 說明
>=0xc000 0000
核心虛擬儲存器
使用者**不可見區域
<0xc000 0000
stack(使用者棧)
esp指向棧頂 ↓
↑空閒記憶體
>=0x4000 0000
檔案對映區
<0x4000 0000
↑ 空閒記憶體
heap(執行時堆)
通過brk/sbrk系統呼叫擴大堆,向上增長。
.data、.bss(讀寫段)
從可執行檔案中載入
>=0x0804 8000
.init、.text、.rodata(唯讀段)
從可執行檔案中載入
<0x0804 8000
保留區域
未完待續,先去吃飯
型別記憶體模型(物件記憶體模型)
型別的記憶體模型的3個問題 1 包含什麼 附加資訊 2 怎麼布局 記憶體對齊 3 使用場景 怎麼使用附加資訊 除了包含結構型別的顯式成員變數外,型別記憶體模型需要解決附加資訊的引入問題 1 附加資訊 opaque 有哪些 型別資訊 函式資訊 繼承資訊 記憶體計數等 2 為什麼有附加資訊 1 解決多型...
C 基礎 記憶體模型記憶體分割槽模型
區 存放函式體的二進位制 由作業系統進行管理 全域性區 存放全域性變數和靜態變數以及常量 棧區 由編譯器自動分配釋放,存放函式的引數值 區域性變數等 堆區 由程式設計師分配和釋放,若程式設計師不釋放,程式結束時由作業系統 存放cpu執行的機器指令,區是共享的,只有乙份 是唯讀的。存放全域性變數 定義...
jvm記憶體模型 JVM記憶體模型詳情解析
一 結構圖 note string常量池 存在 堆記憶體中 二 各部分詳情解析 1 堆1 老年代 物件年齡 經過一次 monitor gc 年齡加1 15 的會存到 老年代 2 年輕代 3 常量池 string常量 儲存在堆中 2 虛擬機器棧 1 區域性變數表 2 運算元棧 3 動態鏈結 4 方法出...