記憶體位址在0x7ff16473d000,相當於140,674,749,157,376(127t965gb(131013gb)處開始,47位最大是128tb,131072gb),如下,也就是在使用者空間(0~0x7fff ffff ffff,128gb)快頂部(差59gb)的位置。
因為48bit空間也要滿足「兩頭頂格」的習慣,整個可用位址範圍變成了0~0x7fff ffff ffff和0x8000 0000 0000~0xffff ffff ffff兩個不連續的位址空間上的的幾個更加離散的小島。以首位區分或者理解為正負符號,linux kernel使用「1」作為系統位址空間,使用「0」作為使用者位址空間(小於47bit可分配給使用者空間)。
雖然段從低到高分配,棧從高到低分配,本質上都是一樣的,就像陣列從頭分配還是從尾分配,儲存上都是從前往後,從效率角度思考的優化結論,所以指標操作都是++為主。
上右圖共享記憶體段中還包含了動態鏈結庫。其二,有些地方寫著共享記憶體段是從下往上、有些是從上往下(如上右圖),但肯定有個基址(要分配兩個驗證下?),從實際角度來看,從上往下更合適,為什麼?因為棧空間通過核心最大程序數就能估計出來,堆大小估計不出來,避免堆申請越界,所以從上往下是更合適的。
對於linux程式而言,有乙個非常重要的可執行檔案格式elf(executable and linkable format),它是物件檔案、可執行檔案、庫檔案、core dump檔案的格式。位於使用者空間的底部,通常在啟動時就確定並且不變。其組成部分從下到上為:
對可執行檔案而言,主要有4部分:.text, .data, .rodata和.bss(未初始化的資料),readelf -s execname可以檢視每部分的相對位置。data+bss+heap的大小由rlimit_data控制最大值。棧大小由rlimit_stack控制。(1)使用者空間:0x0000_0000_0000_0000到0x0000_ffff_ffff_ffff,一共有256tb。一般只用128tb,所以只會到0x7fff ffff ffff。
(2)非規範區域
(3)核心空間:0xffff_0000_0000_0000到0xffff_ffff_ffff_ffff。一共有256tb。一般只用128tb。應用程式設計不可見。
核心空間又做了如下細分:
所以更準確的64為記憶體劃分如下:
綠色是使用者區,黃色是核心態。
elf各個部分的操作通常如下:
交換區也是由頁表管理的。
從下可知,heap是從低到高增長,共享記憶體從高到低。
0x7f開頭的都是共享記憶體塊或其中的某個變數。
程式**段、資料段對映到可執行檔案的物理實現如下:
雖然大多數程序不會訪問同一虛擬記憶體,但是也是可以的,例如程序間通訊常用的共享記憶體技術。如下:
待續。。
待續參考:
記憶體位址 位寬與容量
首先說明一下單位 1k 2 10,1m 2 20 1mb 1m byte 2 20 byte 8 2 20 bit 1mb 1m bit 2 20 bit 儲存容量 定址範圍 x 計算機處理位寬 字長 注意位址一般用十六進製制表示,0x1表示2 1,0x3表示2 2,0x7表示2 3,0xf表示2 ...
go語言記憶體,位址,指標
指標就是位址 列印出變數的記憶體和位址 a可以取到a的位址 簡單說可以說位址就是索引,就是門牌號,記憶體就是倉庫,裡面存了東西,存了值 package main import fmt func main int儲存int的位址,int儲存int的位址 定義乙個變數p,型別為 int var p in...
(語法)記憶體位址和指標《一》
根據這段時間的學習深深感覺到應該要深入理解記憶體機制和指標的用法真的很重要,這是第一篇,也是目前對記憶體和指標的認識的總結。記憶體 就好像乙個容器,可以裝納資料在裡面,這個容器不是一整塊的,它是分了很多很多的小格仔,即記憶體中的位,每個格仔裝乙個0或者1,而我們要放到容器中的資料實際上也是要將他分解...