一、 擷取系統資訊
我們可以調用系統資訊擷取函數來獲得本系統的頁面大小、分配粒度的大小等資訊。
系統資訊擷取函數:
VOID GetSystemInfo(LPSYSTEM_INFO psinf);
參數類型:
LPSYSTEM_INFO psinf 用於返回系統資訊的資料結構
所包含資訊:
dwPageSize:CPU頁面的大小
lpMinimumApplicationAddress:進程可用的地址空間中的最小地址
lpMaximumApplicationAddress:進程可用的地址空間中的最大地址
dwAllocationGranularity:保留的地址空間地區的分配粒度
dwNumberOfProcessors:電腦中CPU的數目
dwActiveProcessorMask:用於指明那個CPU是活動的
wProcessorArchitecture:處理器結構
wProcessorLevel:更詳細的處理器結構
wProcessorRevision:更詳細的處理機層級
驗證程式:
#include <iostream> #include <windows.h> using namespace std; void main() { /*擷取進程資訊*/ LPSYSTEM_INFO systemInfo = new SYSTEM_INFO(); GetSystemInfo(systemInfo); cout << "Page Size :" << systemInfo->dwPageSize << endl; cout << "Allocation Granularity : " << systemInfo->dwAllocationGranularity << endl; cout << "Minimum application address : " << systemInfo->lpMinimumApplicationAddress << endl; cout << "Maxmum application address : " << systemInfo->lpMaximumApplicationAddress << endl; cout << "Number of processors : " << systemInfo->dwNumberOfProcessors << endl; cout << "Active processor mask : " << systemInfo->dwActiveProcessorMask << endl; cout << "Processor architecture : " << systemInfo->wProcessorArchitecture << endl; cout << "Processor level : " << systemInfo->wProcessorLevel << endl; cout << "Processor revision : " << systemInfo->wProcessorRevision << endl; cout << endl; system("pause"); }
輸出結果:
Page Size :4096
Allocation Granularity : 65536
Minimum application address : 00010000
Maxmum application address : 7FFEFFFF
Number of processors : 2
Active processor mask : 3
Processor architecture : 0
Processor level : 6
Processor revision : 3846
二、 查看虛擬記憶體狀態
我們可以通過相關函數檢索當前記憶體狀態的動態資訊。
擷取函數:
GlobalMemoryStatus(LPMEMORYSTATUS pmst); /*記憶體小於4G*/
GlobalMemoryStatusEx(LPMEMORYSTATUSEX pmst); /*記憶體大於4G或合計分頁檔大小大於4G*/
函數參數:
LPMEMORYSTATUS pmst:用於返回資訊的資料結構
LPMEMORYSTATUSEX pmst:用於返回資訊的資料結構
包含資訊:
dwLength:參數結構體的位元組數
dwTotalPhys:實體儲存體器的總位元組數
dwAvailPhys:可供分配的實體儲存體器的總位元組數
dwTotalPageFile:硬碟上調頁檔案中包含的最大位元組數
dwAvailPageFile:調頁檔案中尚未提交給任何進程的總的位元組數
dwTotalVirtual:每個近處的地址空間中私人的總位元組數
dwAvailVirtual:當前進程中所有空閑地區的總和
驗證程式:
#include <iostream> #include <windows.h> using namespace std; void main() { /*擷取虛擬記憶體狀態*/ LPMEMORYSTATUS memoryStatus = new MEMORYSTATUS(); memoryStatus->dwLength = sizeof(MEMORYSTATUS); GlobalMemoryStatus(memoryStatus); cout << "memoryStatus" << endl; cout << "MemoryStatus length : " << memoryStatus->dwLength << endl; cout << endl; cout << "Total Phys : " << memoryStatus->dwTotalPhys << endl; cout << "Avail Phys : " << memoryStatus->dwAvailPhys << endl; cout << endl; cout << "Total Page File : " << memoryStatus->dwTotalPageFile << endl; cout << "Avail Page File : " << memoryStatus->dwAvailPageFile << endl; cout << endl; cout << "Total Virtual : " << memoryStatus->dwTotalVirtual << endl; cout << "Avail Virtual : " << memoryStatus->dwAvailVirtual << endl; cout << endl; cout << "memoryStatusEx" << endl; /*擷取記憶體大於4G,或者合計分頁檔的大小大於4G情況下的虛擬記憶體狀態*/ LPMEMORYSTATUSEX memoryStatusEx = new MEMORYSTATUSEX(); memoryStatusEx->dwLength = sizeof(MEMORYSTATUSEX); GlobalMemoryStatusEx(memoryStatusEx); cout << "MemoryStatus length : " << memoryStatusEx->dwLength << endl; cout << endl; cout << "Total Phys : " << memoryStatusEx->ullTotalPhys << endl; cout << "Avail Phys : " << memoryStatusEx->ullAvailPhys << endl; cout << endl; cout << "Total Page File : " << memoryStatusEx->ullTotalPageFile << endl; cout << "Avail Page File : " << memoryStatusEx->ullAvailPageFile << endl; cout << endl; cout << "Total Virtual : " << memoryStatusEx->ullTotalVirtual << endl; cout << "Avail Virtual : " << memoryStatusEx->ullAvailVirtual << endl; cout << "Avail Extended Virtual : " << memoryStatusEx->ullAvailExtendedVirtual << endl; system("pause"); }
輸出結果:
memoryStatus
MemoryStatus length : 32
Total Phys : 2147483647
Avail Phys : 2147483647
Total Page File : 4294967295
Avail Page File : 3689095168
Total Virtual : 2147352576
Avail Virtual : 2140684288
memoryStatusEx
MemoryStatus length : 64
Total Phys : 3218522112
Avail Phys : 2473451520
Total Page File : 4421079040
Avail Page File : 3689095168
Total Virtual : 2147352576
Avail Virtual : 2140684288
Avail Extended Virtual : 0
三、 確定地址空間的狀態
我們可以通過調用相應函數來確定地址空間真能幹記憶體位址的大小、儲存空間類型、保護屬性等資訊。
擷取地址空間狀態的函數:
VirtualQuery(LPCVOID pvAddr, PMEMORY_BASIC_INFORMATION pmbi, DWORD dwLength);
函數參數:
LPCVOID pvAddr:指標類型,包含需要查詢其資訊的記憶體位址
PMEMORY_BASIC_INFORMATION pmbi:用於返回資訊的資料結構
DWORD dwLength:用於設定EMORY_BASIC_INFORMATION結構大小
包含資訊:
BaseAddress:經過四捨五入的頁面邊界值
AllocationBase:包含pvAddress參數中捨得的地址地區的基地址
AllocationProtect:該地址空間地區初次保留時的保護屬性
Protect:該地區的保護屬性,包括(R E W)
State:所有相鄰頁面的狀態,包括自由(MEM_FREE)、保留(MEM_RESERVE)、提交(MEM_COMMIT)
Type:所有相鄰頁面的儲存類型,包括映像(MEM_IMAGE)、映射(MEM_MAPPED)、私人(EM__PRIVATE)
註:私人受系統頁檔案的支援,映像受記憶體映射的映像檔案支援(exe/dll)。
驗證程式:
#include <iostream> #include <windows.h> using namespace std; void main() { /*擷取地址空間的狀態*/ PMEMORY_BASIC_INFORMATION memoryBasicInfo = new MEMORY_BASIC_INFORMATION(); PVOID addr = NULL; /*作為指標變數單獨使用,此處不需與其他地址綁定*/ cout << "Virtual Memory Status" << endl; while(true) { VirtualQuery((void *)addr, memoryBasicInfo, sizeof(MEMORY_BASIC_INFORMATION)); cout << memoryBasicInfo->BaseAddress << "/t" << memoryBasicInfo->AllocationBase << "/t" << memoryBasicInfo->RegionSize << "/t" ; switch(memoryBasicInfo->State) { case MEM_FREE: { cout << "free"; break; } case MEM_RESERVE: { cout << "reserve"; break; } case MEM_COMMIT: { cout << "commit"; break; } } cout << "/t"; switch(memoryBasicInfo->AllocationProtect) { case PAGE_NOACCESS: { cout << "N"; break; } case PAGE_READONLY: { cout << "R"; break; } case PAGE_EXECUTE: { cout << "E"; break; } case PAGE_EXECUTE_READ: { cout << "ER"; break; } case PAGE_EXECUTE_READWRITE: { cout << "ERW"; break; } } cout << "/t"; switch(memoryBasicInfo->Protect) { case PAGE_NOACCESS: { cout << "N"; break; } case PAGE_READONLY: { cout << "R"; break; } case PAGE_EXECUTE: { cout << "E"; break; } case PAGE_EXECUTE_READ: { cout << "ER"; break; } case PAGE_EXECUTE_READWRITE: { cout << "ERW"; } } cout << "/t"; switch(memoryBasicInfo->Type) { case MEM_IMAGE: { cout << "image"; break; } case MEM_MAPPED: { cout << "mapped"; break; } case MEM_PRIVATE: { cout << "private"; break; } } cout << endl; if((int)memoryBasicInfo->BaseAddress + memoryBasicInfo->RegionSize >= 0x7FFF0000) { break; } addr = ((PBYTE)memoryBasicInfo->BaseAddress + memoryBasicInfo->RegionSize); } system("pause"); }
輸出結果:
Virtual Memory Status
00000000 00000000 65536 free N
00010000 00010000 12288 commit private
00013000 00000000 53248 free N
00020000 00020000 4096 commit private
00021000 00000000 61440 free N
00030000 00030000 1036288 reserve private
0012D000 00030000 4096 commit private
0012E000 00030000 8192 commit private
00130000 00130000 12288 commit R R mapped
00133000 00000000 53248 free N
00140000 00140000 12288 commit private
00143000 00140000 1036288 reserve private
00240000 00240000 24576 commit private
00246000 00240000 40960 reserve private
00250000 00250000 12288 commit mapped
00253000 00250000 53248 reserve mapped
00260000 00260000 90112 commit R R mapped
00276000 00000000 40960 free N
00280000 00280000 266240 commit R R mapped
002C1000 00000000 61440 free N
002D0000 002D0000 266240 commit R R mapped
00311000 00000000 61440 free N
00320000 00320000 24576 commit R R mapped
00326000 00000000 40960 free N
00330000 00330000 266240 commit R R mapped
00371000 00000000 61440 free N
00380000 00380000 16384 commit private
00384000 00380000 49152 reserve private
00390000 00390000 12288 commit R R mapped
00393000 00000000 446464 free N
00400000 00400000 4096 commit R image
00401000 00400000 102400 commit image
0041A000 00400000 229376 commit ER image
00452000 00400000 28672 commit R image
00459000 00400000 4096 commit image
0045A000 00400000 20480 commit image
0045F000 00000000 2084179968 free N
7C800000 7C800000 4096 commit R image
7C801000 7C800000 540672 commit ER image
7C885000 7C800000 12288 commit image
7C888000 7C800000 8192 commit image
7C88A000 7C800000 606208 commit R image
7C91E000 00000000 8192 free N
7C920000 7C920000 4096 commit R image
7C921000 7C920000 499712 commit ER image
7C99B000 7C920000 12288 commit image
7C99E000 7C920000 8192 commit image
7C9A0000 7C920000 77824 commit R image
7C9B3000 00000000 47435776 free N
7F6F0000 7F6F0000 28672 commit ER ER mapped
7F6F7000 7F6F0000 1019904 reserve ER mapped
7F7F0000 00000000 8060928 free N
7FFA0000 7FFA0000 208896 commit R R mapped
7FFD3000 00000000 20480 free N
7FFD8000 7FFD8000 4096 commit private
7FFD9000 00000000 24576 free N
7FFDF000 7FFDF000 4096 commit private
7FFE0000 7FFE0000 4096 commit R R private
7FFE1000 7FFE0000 61440 reserve R N private