module在上面被叫住image,實際上就是被載入到記憶體的exe和dll檔案, 我們可以通過lm命令來檢視所有的模組分布情況:
上面可以看到每個模組的記憶體起始位址,那麼各個模組具體內部又是如何分布,它和磁碟上的dll(exe)檔案又是什麼關係呢?
實際上記憶體的中dll和磁碟上的dll檔案非常相似,系統在載入時只是根據頁面大小(一般4k)作了一些對齊,另外有些資料節如果執行時用不到(比如dll的重定位節)就不會被載入.
我們在!address檢視記憶體空間時,可以看到taskmgr.exe模組的記憶體分布如下:
上面可以看到taskmgr.exe模組在記憶體中分為4塊,第一塊是唯讀的, 實際上是pe檔案頭;第二塊是可執行的,實際上就是**節(.text);第三塊是可讀寫的,實際上資料節(.data); 最後一塊也是唯讀的,實際上資源節(.rsrc)。
要詳細的了解taskmgr.exe模組的檔案頭屬性,可以通過!dh [module address]來檢視, 輸入!dh 1000000,檢視結果:
上面的執行結果可以驗證我們關於taskmgr.exe模組內部分布的猜想.
(2)heap
heap實際上就是堆,我們所有new(malloc)出來的記憶體就是分布在堆裡,每個程式會有若干個堆,有些是系統建立的,也有的是c/c++執行庫建立的,當然我們自己也可以建立私有堆.我們可以通過!heap命令來檢視堆的使用情況.
可以看到taskmgr.exe一共有9個堆。
!heap命令非常強大,通過開啟頁堆功能,可以很方便的讓我們跟蹤所有堆記憶體的分配和使用情況,以後有機會再細說heap相關的.
(3)stack
stack即我們通常所說的棧,我們的區域性變數就是分配在棧上面。說到棧就要說到執行緒,我們的**都是通過執行緒跑起來的,每個執行緒包含2塊東西,一塊是執行緒核心物件,還有一塊就是堆疊,執行緒執行過程也是堆疊不斷壓棧和出棧的過程。
我們可以通!address -f:stack 來檢視堆疊的分布情況:
從上圖我們可以看到taskmgr.exe一共有4個執行緒, 對應著4個堆疊, 同時也可以看到每個堆疊記憶體的起始位址。
如果有興趣,我們也可以看下每個執行緒的堆疊情況, 輸入~* kp
可以看到相應的4個執行緒堆疊,最後乙個執行緒(debugbreakpoint)看起來有些奇怪,實際上它是偵錯程式為除錯而插入的,不是真正的屬於taskmgr.exe, 所以任務管理器實際上一共應該有3個執行緒.
如果是image上,那麼是在哪個模組中,這個位址是屬於該模組的**段(.text)還是資料段(.data),如果是**段,又是屬於哪個函式?
如果是heap上,那麼究竟是在哪個堆裡面,是我們new出來的嗎,是在什麼時候new的(new時堆疊狀況)?
如果是在stack上,那麼究竟是屬於哪個執行緒的堆疊,當時執行緒的堆疊是怎麼樣?
總之,程式在記憶體中執行,只有你真正理解了記憶體,你才能真正懂計算機。
C 程式記憶體分割槽通俗理解
知識點 1 棧區 stack 由編譯器自動分配釋放,存放函式的引數值,區域性變數值等。2 堆區 heap 一般由程式設計師分配釋放,隨叫隨到,揮之即走。3 全域性 靜態區 global static 全域性變數和靜態變數的儲存是放在一起的,在程式編譯時分配。4 文字常量區 存放常量字串。常量不能修改...
程式設計師對記憶體的理解
收藏 在c和c 語言開發中,指標 記憶體一直是學習的重點。因為c語言作為一種偏底層的中低階語言,提供了大量的記憶體直接操作的方法,這一方面使程式的靈活度最大化,同時也為bug埋下很多隱患。因此,無論如何,我們都要對記憶體有乙個清晰的理解。32位作業系統支援4gb記憶體的連續訪問,但通常把記憶體分為兩...
理解記憶體概念
儘管記憶體這個詞常常掛在我們的嘴上,但是,有多少人真正了解記憶體 理解記憶體概念呢?對剛剛步入電腦世界的初學者來說,基本記憶體 上位記憶體 高階記憶體 擴充套件記憶體 擴充記憶體 保留記憶體等概念更是玄之又玄,難以徹底理解。所以我們特地介紹一下記憶體的基本概念。基本知識 記憶體 記憶體就是儲存程式以...