1
float[][, , ,] tempData = new float[30][, , ,];

private void InitTempData()
{
    const int FocusSize = 400;
    try
    {
        for (int i = 0; i < 30; i++)
        {
            tempData[i] = new float[40, FocusSize, FocusSize, 5];
        }
    }
    catch (OutOfMemoryException ex)
    {
        MessageBox.Show(ex.Message);
    }
}

次のような配列サイズの tempData を使用する必要があります。

tempData[30][40, 400, 400, 5]

しかし、私がこれまでに経験したことはOutOfMemory、サイズが 100 を超える新しい Array を定義するとうまくいきます。

私が考えているアイデアは、サイズが 100 の 4 つの新しい配列を初期化することです。そして、以下のように異なる初期カウンターで始まる 4 つの新しい配列を使用します。

float[][, , ,] tempData0 = new float[30][, , ,];
float[][, , ,] tempData1 = new float[30][, , ,];
float[][, , ,] tempData2 = new float[30][, , ,];
float[][, , ,] tempData3 = new float[30][, , ,];

private void InitTempData()
{
    const int FocusSize = 100;
    try
    {
        for (int i = 0; i < 30; i++)
        {
            tempData0[i] = new float[40, FocusSize, FocusSize, 5];
            tempData1[i] = new float[40, FocusSize, FocusSize, 5];
            tempData2[i] = new float[40, FocusSize, FocusSize, 5];
            tempData3[i] = new float[40, FocusSize, FocusSize, 5];
        }
    }
    catch (OutOfMemoryException ex)
    {
        MessageBox.Show(ex.Message);
    }
}

//Use the tempData0, tempData1, tempData2, and tempData3 with different initial counter
for (int i = 0; i < 30; i++)
{
    for (int x = 0; x < FocusSize; x++)
    {
        for (int z = 0; z < FocusSize; z++)
        {
            //Use tempData0 here
        }
    }
}

for (int i = 0; i < 30; i++)
{
    for (int x = FocusSize; x < FocusSize * 2; x++)
    {
        for (int z = FocusSize; z < FocusSize * 2; z++)
        {
            //Use tempData1 here
        }
    }
}

for (int i = 0; i < 30; i++)
{
    for (int x = FocusSize * 2; x < FocusSize * 3; x++)
    {
        for (int z = FocusSize * 2; z < FocusSize * 3; z++)
        {
            //Use tempData2 here
        }
    }
}

私の上記の考えはそれを行う正しい方法ですか?または、配列の使用を拡張する他のオプションはありますか?

4

3 に答える 3

2

これは非常に大きな配列です。

30 * 40 * 400 * 400 * 5 * (4 bytes) ~= 3.6GB total

十分な空きメモリがあり、64 ビット プロセス (> 2/3GB に必要) を実行していると仮定すると、配列がメモリ内の連続したブロックとして配置されるため、壁にぶつかる可能性があります。

[30][40,400,400,5] を使用した上記の例では、CLR に 30 個の 128Mb メモリ ブロックを検索するように要求しています。

参照: http://blogs.msdn.com/b/ericlippert/archive/2009/06/08/out-of-memory-does-not-refer-to-physical-memory.aspx

より小さな配列を参照するリストを作成するか、単純に「ギザギザ」配列として宣言して、連続したメモリの問題を回避できます (配列の配列を逆参照する際のパフォーマンスが最悪になります)。

すなわち float[30][40][400][400][5]

于 2013-08-13T02:01:25.893 に答える
0

Windows 32 ビット (86x) を使用している場合は、新しい要素を追加する前にメモリ サイズを確認する必要があります。

// Here you have to check that the current used memory in your process; this shall not exceed more than 2 GB;
// If you are using  /LARGEADDRESSAWARE than not exceed 4 GB
If (MemoryHelper.CanAllocateObject())
{
 // here add a new elements
}

現在のプロセスを取得して使用するには:
Process proc = Process.GetCurrentProcess(); proc.PrivateMemorySize64;
http://msdn.microsoft.com/en-us/library/s80a75e5%28VS.80%29.aspx

于 2013-08-13T07:53:33.763 に答える