2016-09-13 46 views
3

我想在C#中調用Windows的'GetSystemInfo() API函數以檢索maximumApplicationAddressminimumApplicationAddress以掃描計算機的內存。GetSystemInfo()爲最大應用程序地址返回不同的值

我寫了一個簡單的程序,輸出這些值:

SYSTEM_INFO sys_info = new SYSTEM_INFO(); 
GetSystemInfo(out sys_info); 
Console.WriteLine("Min Address: {0:X}", sys_info.minimumApplicationAddress.ToUInt64()); 
Console.WriteLine("Max Address: {0:X}", sys_info.maximumApplicationAddress.ToUInt64()); 

當我運行這個程序,調試器(使用啓動按鈕),就說明這一點:

Min Address: 10000 
Max Address: 7FFEFFFF 

但是,當我構建它,然後運行可執行文件,它顯示了這一點:

Min Address: 10000 
Max Address: FFFEFFFF 

Max Addr對我來說埃斯特有點陌生。你能解釋一下原因嗎?

+1

第一個7FFEFFFF是2GB,第二個是4GB。根據[這](http://stackoverflow.com/questions/11891593/the-maximum-amount-of-memory-any-single-process-on-windows-can-address)它可能是這樣的:「32位的64位操作系統:2 GB,除非設置爲大的地址空間感知,在這種情況下4 GB。「 - 所以也許調試器正在使用非大地址感知代碼,但構建版本是? – Quantic

+0

是的,你說得對。根據鏈接的問題,運行'editbin/LARGEADDRESSAWARE:NO Program.exe'使得構建的程序像調試器一樣行爲 – Ahmad

回答

4

這是一個實施細節,應該不關心你。您看到FFFEFFFF是因爲您在64位操作系統上運行,並且您的EXE項目的Platform目標被設置爲AnyCPU,並且選中了「首選32位」選項。 .NET項目的默認設置。 AnyCPU選項獲取可執行文件頭集中的/ LARGEADDRESSAWARE選項位,告訴操作系統在64位操作系統上提供4 GB的地址空間。您將始終在32位操作系統上獲得7FFEFFFF。

將平臺目標設置爲x86以查看差異。項目>屬性>生成選項卡。

如果您希望Debug版本生成相同的值,那麼您需要使用Project> Properties> Debugging>取消選中「啓用Visual Studio宿主進程」選項。託管過程是另一個EXE,yourproject.vshost.exe。它沒有設置選項,可以說是一個錯誤。但最有可能的是一個堅韌不拔的問題的便捷捷徑。

您可以使用Dumpbin.exe/headers看到兩者之間的區別。報告爲「應用程序可以處理大型(> 2GB)地址」。

0

要檢查應用程序的地址空間,最好使用VirtualQueryVirtualQueryEx Windows API函數,而不是逐頁掃描內存(或64KB區域64KB區域)。 Ex變體允許您檢查與您不同的進程的地址空間。

您的原始問題已在上面的評論中得到解答。

+0

我將'GetSystemInfo()'給出的值傳遞給'VirtualQueryEx()'來查找分配了哪些頁面到進程 – Ahmad

+0

根本沒有必要使用這些地址。只需將NULL地址傳遞給第一個'VirtualQueryEx'調用即可。你會得到一個描述從該地址開始的區域的「MEMORY_BASIC_INFORMATION」結構。該結構還包括該區域的大小,因此在第二次調用'VirtualQueryEx'時,您將'NULL + RegionSize'作爲地址值傳遞。等等。 'MEMORY_BASIC_INFORMATION'還會通知您有關該區域內的頁面(自由,保留,提交),其保護(讀取,寫入,執行)等內容。 –