12

32 ビット ライブラリとリンクする必要があり、可能な限り最大量のメモリを使用する必要がある C# アプリがあります (イメージング アプリ)。XP64 デスクトップでアプリを実行するため、WOW64 を使用し、Visual Studio for x86 でビルドをターゲットにしています (そしてeditbin /largeaddressawareポストビルドを実行しています)。いくつかの問題が発生しています:

  • Visual Studio のビルトイン デバッガーでは、2 GB のメモリしか使用できません (アプリに最大 1.5 GB とオーバーヘッドを加えたもの)。

  • コマンド ラインから実行すると、アプリは 3 GB のメモリを認識できますが、Microsoft のドキュメントでは 4 GB を表示する必要があると記載されているようです。

WOW64 C# アプリを取得して、プラットフォームが提供できる完全な 4 GB を表示する方法を誰か教えてもらえますか?

また、Visual Studio (VS 2008、別名 VS90) デバッガーが/largeaddressawareビットに従い、アプリのメモリを 2 GB に制限するのをやめる方法を教えてもらえますか?

VS80 と VS90 でも同じ動作が見られます。また、.NET Framework 3.5、3.0、2.0 の間でも違いはありません。問題を説明する簡単な C# プログラムを次に示します。x86 用にビルドしeditbin /largeaddressaware、組み込みデバッガーで実行する場合とコマンド ラインから実行する場合を比較して、C# で使用できるメモリの違いを確認します。

namespace MemoryAllocTest
{
class Program
{
    static void Main(string[] args)
    {
        const int allocSize = 1024 * 1024;
        List<byte[]> myMem = new List<byte[]>();
        UInt64 totalAlloc = 0;

        while (true)
        {
            myMem.Add(new byte[allocSize]);
            totalAlloc += allocSize;
            Console.WriteLine("{0} allocs: {1}MB total", 
             myMem.Count, totalAlloc / (1024 * 1024));
        }
    }
}
}
4

6 に答える 6

5

Visual Studio (VS 2008、別名 VS90) デバッガーが /largeaddressaware ビットに従い、アプリのメモリを 2 GB に制限するのをやめる方法を教えてもらえますか?

これには 2 つの手順が必要です。どちらもプロジェクトのプロパティにあります。

  • ビルド イベント タブで、ビルド後のステップをセットアップして、editbin /largeaware $(TargetPath) を実行します。
  • [デバッグ] タブで、[Visual Studio ホスティング プロセスを有効にする] のチェックを外します

この 2 つのステップで、サンプル プログラムは 3045MB まで実行されました。

于 2009-04-29T22:44:45.683 に答える
3

回答してくださった皆様、ありがとうございました。このサイトは本当に素晴らしいです!

WOW64 では実際に 4 GB のユーザー空間に達しているように見えますが、マネージ コードによって割り当てられたメモリが大きくなるにつれて、ガベージ コレクターのオーバーヘッド (またはおそらく安全マージン) がかなり大きくなるように思われます (控えめな推測)。テスト アプリを WOW64 (コマンド ライン、LARGEADDRESSAWARE を使用) で実行すると、合計で 3175 MB の割り当てが得られます。4GT パラメータ セットを使用して WIN32 XP マシンで実行すると、合計で 2857MB の割り当てが得られます。したがって、追加のユーザー モード メモリを 1 ギガ追加しても、C# アプリ レベルでは最大 318MB しか増加しません!

(割り当てが失敗したときに割り当てユニットのサイズを半分にするようにテスト プログラムを変更し、「通常の」アプリケーションが取得できる制限を少し超えるために、ガベージ コレクションを戦略的に強制する呼び出しを追加しました - - 修正したコードを投稿してほしい場合は、ここにメモを残してください。)

とにかく、皆さんにもう一度感謝します。システムは正常に動作しているように見えますが、管理された環境は、追加のメモリ ギガによって予想よりも改善されません。

于 2009-04-30T17:23:06.667 に答える
2

マイクロソフトから:

Boot.ini ファイルで /3GB スイッチを使用しない限り、プロセスとアプリケーションの仮想アドレス空間は 2 GB に制限されます。システムの物理 RAM が 16 GB を超え、/3GB スイッチが使用されている場合、オペレーティング システムは、/3GB スイッチが削除されるまで、追加の RAM を無視します。これは、より多くのページ テーブル エントリをサポートするために必要なカーネルのサイズが大きくなるためです。管理者は、/3GB の機能を黙って自動的に失うことは避けたいと考えています。したがって、管理者はこの設定を明示的に変更する必要があります。/3GB スイッチは、使用するアプリケーションに 3 GB の仮想アドレス空間を割り当てます。 IMAGE_FILE_LARGE_ADDRESS_AWAREプロセスヘッダーで。このスイッチを使用すると、アプリケーションは 2 GB を超える 1 GB の追加の仮想アドレス空間をアドレス指定できます。

于 2009-04-29T19:42:24.733 に答える
2

使用している .NET の正確なバージョンは何ですか? この Connect レポートは、.NET 2.0 で見られるが、.NET 2.0SP1 で修正された同じ問題に関するものです (私が知る限り)。

x64 マシンで 2.0SP1 (またはそれ以降) がオンになっていない場合は、試してみる価値があります...

于 2009-04-29T19:43:12.720 に答える
2

投稿から簡単なサンプル アプリを作成し、クラッシュさせて、WinDbg をアタッチしました。

!address -summary は、プロセスの有効なユーザー モード アドレス空間を表示します。

0:003> !address -summary
 TEB fffdd000 in range fffdb000 fffde000
 TEB fffda000 in range fffd8000 fffdb000
 TEB fffd7000 in range fffd5000 fffd8000
 TEB fffaf000 in range fffad000 fffb0000
 ProcessParametrs 004c2b40 in range 004c0000 00535000
 Environment 004c1978 in range 004c0000 00535000

-------------------- Usage SUMMARY --------------------------
    TotSize (      KB)   Pct(Tots) Pct(Busy)   Usage
   e7d2e000 ( 3798200) : 90.56%    98.77%    : RegionUsageIsVAD
   1547b000 (  348652) : 08.31%    00.00%    : RegionUsageFree
    2887000 (   41500) : 00.99%    01.08%    : RegionUsageImage
     3ff000 (    4092) : 00.10%    00.11%    : RegionUsageStack
          0 (       0) : 00.00%    00.00%    : RegionUsageTeb
     1c0000 (    1792) : 00.04%    00.05%    : RegionUsageHeap
          0 (       0) : 00.00%    00.00%    : RegionUsagePageHeap
       1000 (       4) : 00.00%    00.00%    : RegionUsagePeb
          0 (       0) : 00.00%    00.00%    : RegionUsageProcessParametrs
          0 (       0) : 00.00%    00.00%    : RegionUsageEnvironmentBlock
       **Tot: ffff0000 (4194240 KB)** Busy: eab75000 (3845588 KB)

-------------------- Type SUMMARY --------------------------
    TotSize (      KB)   Pct(Tots)  Usage
   1547b000 (  348652) : 08.31%   : <free>
    2aa3000 (   43660) : 01.04%   : MEM_IMAGE
    1f6a000 (   32168) : 00.77%   : MEM_MAPPED
   e6168000 ( 3769760) : 89.88%   : MEM_PRIVATE

-------------------- State SUMMARY --------------------------
    TotSize (      KB)   Pct(Tots)  Usage
   db838000 ( 3596512) : 85.75%   : MEM_COMMIT
   1547b000 (  348652) : 08.31%   : MEM_FREE
    f33d000 (  249076) : 05.94%   : MEM_RESERVE

Largest free region: Base fbfc0000 - Size 03fed000 (65460 KB)

Tot: ffff0000 (4194240 KB) に基づくと、4GB の有効なユーザー モード領域があります。

また、最大の空きブロックは 65,460KB であり、より多くのメモリを割り当てることができるはずです。

于 2009-04-29T21:50:53.833 に答える
1

4 GB をすべて表示できることを意味する場所を投稿できますか? ああ、たぶんここ:このリンクの興味深い情報

アドレス可能なメモリの違い

ほとんどの開発者が最初に気付くのは、64 ビット プロセッサによって、アドレス指定できる物理メモリと仮想メモリの量が大幅に増加するということです。

* 32-bit applications on 32-bit platforms can address up to 2 GB
* 32-bit applications built with the /LARGEADDRESSAWARE:YES linker flag

32 ビットの Windows XP または Windows Server 2003 では、特別な /3gb ブート オプションを使用して最大 3 GB をアドレス指定できます。これにより、カーネルが 1 GB のみに制限され、一部のドライバーやサービスが失敗する可能性があります。

* 32-bit applications built with the /LARGEADDRESSAWARE:YES linker flag

Windows Vista の 32 ビット バージョン、および Windows Server コード ネーム "Longhorn" オペレーティング システムの 32 ビット バージョンでは、ブート構成データ (BCD) 要素で指定された数までメモリをアドレス指定できます。IncreaseUserVa の値は、デフォルトの 2048 から 3072 (Windows XP の /3gb ブート オプションで構成されたメモリ量と一致します) までの範囲です。残りの 4 GB はカーネルに割り当てられ、ドライバーとサービスの構成に失敗する可能性があります。

BCD の詳細については、MSDN の「ブート構成データ」を参照してください。

* 32-bit applications on 64-bit platforms can address up to 2 GB, or up

/LARGEADDRESSAWARE:YES リンカ フラグを使用して 4 GB に。* 64 ビット アプリケーションは、アドレス指定に 43 ビットを使用します。これにより、アプリケーション用に 8 TB の仮想アドレスが提供され、カーネル用に予約された 8 TB が提供されます。

そうです、(XP64 ターゲットでは) 4 GB を表示できるはずです。

于 2009-04-29T19:43:38.333 に答える