2016-09-13 13 views
3

コンピュータのメモリをスキャンするためにmaximumApplicationAddressminimumApplicationAddressを取得するために、WindowsのGetSystemInfo() API関数をC#で呼び出したいとします。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、2番目は4GBです。 [this](http://stackoverflow.com/questions/11891593/the-maximum-amount-of-memory-any-single-process-on-windows-can-address)によると、次のようになります。 "32 64ビットOSのビット:2 GB、大規模なアドレス空間に対応していない場合、4 GBの場合。 - 多分、デバッガは大規模ではないアドレス対応のコードを使用していますが、ビルドバージョンは? – Quantic

+0

はい、そうです。リンクされた質問によると、 'editbin/LARGEADDRESSAWARE:NO Program.exe'を実行すると、デバッガのようにビルドされたプログラムが動作します。 – Ahmad

答えて

4

に関係しない実装の詳細です。 FFFEFFFFが表示されるのは、64ビットオペレーティングシステムで実行されており、EXEプロジェクトのPlatformターゲットがAnyCPUに設定されており、「32ビット優先」オプションが選択されているためです。 .NETプロジェクトのデフォルト設定。 AnyCPUオプションは、実行可能ファイルヘッダーセットの/ LARGEADDRESSAWAREオプションビットを取得し、64ビットOS上に4 GBのアドレス空間を提供するようにOSに指示します。あなたは常に32ビットOSで7FFEFFFFを取得します。

プラットフォームターゲットをx86に設定して、違いを確認します。プロジェクト>プロパティ>ビルドタブをクリックします。

デバッグビルドで同じ値を生成する場合は、[プロジェクト] - [プロパティ] - [デバッグ] - [Visual Studioホスティングプロセスを有効にする]オプションの選択を解除する必要があります。ホスティングプロセスは別のEXE、yourproject.vshost.exeです。オプションビットが設定されていないことは、間違いなくバグです。しかし、ほとんどの場合、ぎこちない問題のための便利なショートカットです。

Dumpbin.exe /ヘッダーを使用して2つの違いを確認できます。 「アプリケーションは大きな(> 2GB)アドレスを処理できます」と報告されています。

0

アプリケーションのアドレス空間を調べるには、Windows API関数VirtualQueryまたはVirtualQueryExを使用する方が、メモリページをページ単位(または64KB領域/ 64KB領域)でスキャンする方が良いです。 Exバリアントを使用すると、あなたとは異なるプロセスのアドレス空間を調べることができます。

元の質問は上記の文章で回答されています。

+0

' GetSystemInfo() 'によって与えられた値を' VirtualQueryEx() 'に渡して、プロセスへ – Ahmad

+0

これらのアドレスはまったく使用する必要はありません。 NULLアドレスを最初の 'VirtualQueryEx'呼び出しに渡すだけです。そのアドレスで始まる領域を記述する 'MEMORY_BASIC_INFORMATION'構造体を取得します。構造体には領域のサイズも含まれています。したがって、 'VirtualQueryEx'の2度目の呼び出しでは、アドレス値として' NULL + RegionSize'を渡します。その他'MEMORY_BASIC_INFORMATION'は、地域内のページ(自由、予約済み、コミット済み)、保護(読み込み、書き込み、実行)などのステーについても通知します。 –

関連する問題