私の開発IISサーバー(VS2010 IDEから))で、16GBのRAMがインストールされた64ビットWindows 7マシンで次のメソッドを実行しています:
public static MemoryStream copyStreamIntoMemoryStream(Stream stream)
{
long uiLen = stream.Length;
byte[] buff = new byte[0x8000];
int nSz;
MemoryStream ms = new MemoryStream();
try
{
while ((nSz = stream.Read(buff, 0, buff.Length)) != 0)
{
ms.Write(buff, 0, nSz);
}
}
finally
{
Debug.WriteLine("Alloc size=" + ms.Length);
}
return ms;
}
そして私はSystem.OutOfMemoryException
この行:
ms.Write(buff, 0, nSz);
これは、268435456バイトが割り当てられるとスローされます。
Alloc size = 268435456
これは0x10000000または256 MBです。それで、それを機能させるために設定する必要があるグローバル設定があるかどうか疑問に思っていますか?
これがプロジェクトの構成設定のスクリーンショットです。
短い答え-開発サーバーは32ビットプロセスです。
「なぜ256Mbなのか」に対する長い回答
まず、それがどのように機能するかを理解しましょう。
MemoryStreamには、すべてのデータを保持するための内部byte []バッファーがあります。このバッファーの正確なサイズを予測することはできないため、初期値で初期化するだけです。
PositionプロパティとLengthプロパティは実際のバッファーサイズを反映していません。これらは書き込まれたバイト数を反映する論理値であり、実際の物理バッファーサイズよりも簡単に小さくなります。
この内部バッファーがすべてのデータに収まらない場合は、「サイズ変更」する必要がありますが、実際には新しいバッファーの作成前のサイズの2倍のサイズで、古いバッファーからデータをコピーします新しいバッファに。
したがって、バッファの長さが256Mbで、新しいデータを書き込む必要がある場合、.Netはさらに512Mbのデータブロックを見つける必要があります。残りはすべて適切に配置されているため、ヒープは少なくとも768Mbでなければなりません。 OutOfMemoryを受け取ったときのメモリ割り当ての瞬間。
また、デフォルトでは、.Netの配列を含む単一のオブジェクトは2Gbを超えるサイズをとることができないことに注意してください。
さて、これが何が起こっているのかをシミュレートするサンプルです:
byte[] buf = new byte[32768 - 10];
for (; ; )
{
long newSize = (long)buf.Length * 2;
Console.WriteLine(newSize);
if (newSize > int.MaxValue)
{
Console.WriteLine("Now we reach the max 2Gb per single object, stopping");
break;
}
var newbuf = new byte[newSize];
Array.Copy(buf, newbuf, buf.Length);
buf = newbuf;
}
X64/AnyCPUを組み込み、コンソールから実行する場合-すべて問題ありません。
X86でビルドした場合-コンソールで失敗します。
X64に組み込まれているPage_Loadと言って、VS.Net Webサーバーから開くと、失敗します。
IISで同じことをする場合-すべてが大丈夫です。
お役に立てれば。
デフォルトのVS開発サーバーを使用している場合は、x86/32ビットプロセスでコードを実行しています。フルを使用している場合IIS-ほとんどの場合IIS特定のAppPoolはx86(32ビットモード)で実行するように構成されているため、アドレス空間が非常に限られています。 (アプリケーションをLarge Address Awareとしてマークしていない限り2GB)。
IISの場合は、アプリポーリングがx64を実行するように構成されていることを確認してください(デフォルトが不明)。コードのターゲットがAnyCPUまたはx64に設定されていることを確認してください。
スタンドアロンC#アプリケーションの場合-デフォルトではx86またはAnyCPU/Prefer x86でコンパイルされます-ターゲットプラットフォームをx64に変更します。
IISのx64サポートを取得するには、 フルIISをインストール またはインストールIIS Express 8.0(Windows 7に付属する7.5は32ビットのみ) Download IIS 8.0 Express から).
サイドノート: