MEMORY_BASIC_INFORMATION中 BaseAddress 和 AllocationBase 區別

地址空間在運行中映射爲實際的物理頁面。
 
·        區域
區域指的是上述地址空間中的一片連續地址。區域的大小必須是粒度(64k) 的整數倍,不是的話系統自動處理成整數倍。不同CPU粒度大小是不一樣的,大部分都是64K。
區域的狀態有:空閒、私有、映射、映像。
在你的應用程序中,申請空間的過程稱作保留(預訂),可以用VirtualAlloc;刪除空間的過程爲釋放,可以用VirtualFree。
        在程序裏預訂了地址空間以後,你還不可以存取數據,因爲你還沒有付錢,沒有真實的RAM和它關聯。
這時候的區域狀態是私有;
默認情況下,區域狀態是空閒;
當exe或DLL文件被映射進了進程空間後,區域狀態變成映像;
當一般數據文件被映射進了進程空間後,區域狀態變成映射。
 
·        物理存儲器
Windows各系列支持的內存上限是不一樣的,從2G到64G不等。理論上32位CPU,硬件上只能支持4G內存的尋址;能支持超過4G的內存只能靠其他技術來彌補。順便提一下,Windows個人版只能支持最大2G內存,Intel使用Address Windows Extension (AWE) 技術使得尋址範圍爲236=64G。當然,也得操作系統配合。
        內存分配的最小單位是4K或8K,一般來說,根據CPU不同而不同,後面你可以看到可以通過系統函數得到區域粒度和頁面粒度。
 
·        頁文件
頁文件是存在硬盤上的系統文件,它的大小可以在系統屬性裏面設置,它相當於物理內存,所以稱爲虛擬內存。事實上,它的大小是影響系統快慢的關鍵所在,如果物理內存不多的情況下。
       每頁的大小和上述所說內存分配的最小單位是一樣的,通常是4K或8K。
 
映射過程
進程地址空間的地址是虛擬地址,也就是說,當取到指令時,需要把虛擬地址轉化爲物理地址才能夠存取數據。這個工作通過頁目和頁表進行。
 
頁目大小爲4K,其中每一項(32位)保存一個頁表的物理地址;每個頁表大小爲4K,其中每一項(32位)保存一個物理頁的物理地址,一共有1024個頁表。利用這4K+4K*1K=4.4M的空間可以表示進程的1024*1024* (一頁4K) =4G的地址空間。
高10位用來找到1024個頁目項中的一項,取出頁表的物理地址後,利用中10位來得到頁表項的值,根據這個值得到物理頁的地址,由於一頁有4K大小,利用低12位得到單元地址,這樣就可以訪問這個內存單元了。
        每個進程都有自己的一個頁目和頁表,那麼,剛開始進程是怎麼找到頁目所在的物理頁呢?答案是CPU的CR3寄存器會保存當前進程的頁目物理地址。
        當進程被創建時,同時需要創建頁目和頁表,一共需要4.4M。在進程的空間中,0xC030 0000~0xC030 0FFF是用來保存頁目的4k空間。0xC000 0000~0xC03F FFFF是用來保存頁表的4M空間。也就是說程序裏面訪問這些地址你是可以讀取頁目和頁表的具體值的(要工作在內核方式下)。有一點我不明白的是,頁表的空間包含了頁目的空間!
        至於說,頁目和頁表是保存在物理內存還是頁文件中,我覺得,頁目比較常用,應該在物理內存的概率大點,頁表需要時再從頁文件導入物理內存中。
        頁目項和頁表項是一個32位的值,當頁目項第0位爲1時,表明頁表已經在物理內存中;當頁表項第0位爲1時,表明訪問的數據已經在內存中。還有很多數據是否已經被改變,是否可讀寫等標誌。另外,當頁目項第7位爲1時,表明這是一個4M的頁面,這值已經是物理頁地址,用虛擬地址的低22位作爲偏移量。還有很多:數據是否已經被改變、是否可讀寫等標誌。
 



MEMORY_BASIC_INFORMATION這個結構中的兩個成員的區別:

  1. typedef struct _MEMORY_BASIC_INFORMATION {    
  2. PVOID BaseAddress;    
  3. PVOID AllocationBase;    
  4. DWORD AllocationProtect;    
  5. SIZE_T RegionSize;    
  6. DWORD State;    
  7. DWORD Protect;    
  8. DWORD Type;  
  9. } MEMORY_BASIC_INFORMATION,  *PMEMORY_BASIC_INFORMATION;   

  1. <strong>以下引用csdn論壇的觀點,我認爲這解釋地比較清楚了:</strong>  
  2. PVOID BaseAddress;  //該頁的基地址,是VirtualQuery(Ex)第一個參數下舍入下一個頁面的邊界的值  
頁的邊界啓始地址. 在地址形式上類似: 0xXXXXX000(X86,頁大小爲4KB)

  1. PVOID AllocationBase;  

在進程中爲了使用內存,必須保留(Reserved)內存和佔有內存(Committed) -使用VirtualAlloc()函數. VirtualAlloc分配的內存稱爲區域(Region)- 一片連續的頁. 爲了分配效率(?) Windows會以64-KB爲邊界計算區域的啓始地址,所以區域的啓始地址在形式上類似: 0xXXXX0000,這裏的64KB頁就是所謂的分配粒度,因此 AllocationBase正是一個區域(Region)的啓始地址


另外,BaseAddress一定在AllocationBase地址範圍之內
(The page pointed to by the BaseAddress member is contained within this allocation range)
以下是我在應用VirtualQuery函數時MEMORY_BASIC_INFORMATION結構裏面的
PVOID BaseAddress;
PVOID AllocationBase;兩個成員的返回值

=================================
BaseAddress   AllocationBase
0x00401000    0x00400000
0x00401700    0x00400000
0x00401800    0x00400000
0x00401a00    0x00400000

=================================

BaseAddress - the address of the queried memory page ( VirtualQuery(LPCVOID lpAddress,... ).

AllocationBase - the beginning of the allocated memory block. It is used for deallocation. BaseAddress >= AllocationBase.

If you are querying stack then AllocationBase will be the lowest address of the stack (the stack top)
發佈了18 篇原創文章 · 獲贊 2 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章