3

配列のサイズはどれくらいなのだろうか。と思ったのですsize * sizeof(item) + sizeof(pointer)が、配列を参照できるように何バイト割り当てられているのでしょうか?

4

1 に答える 1

8

バイト単位の配列のオーバーヘッドは次のとおりです。

Architecture | Value Type Array | Reference Type Array
    x86              12                   16
    x64              24                   32

これらの値は次のように計算できます

using System;

class Test
{
    const int Size = 100000;

    static void Main()
    {
        Console.WriteLine("Running at {0} bits", IntPtr.Size * 8);

        Tester<string>();
        Tester<double>();

        Console.ReadKey();
    }

    static void Tester<T>()
    {
        var array = new object[Size];
        long initialMemory = GC.GetTotalMemory(true);

        for (int i = 0; i < Size; i++)
        {
            array[i] = new T[0];
        }

        long finalMemory = GC.GetTotalMemory(true);

        GC.KeepAlive(array);

        long total = finalMemory - initialMemory;

        Console.WriteLine("Size of each {0}[]: {1:0.000} bytes", typeof(T).Name,
                          ((double)total) / Size);
    }
}

このコードは、こちらのコードの修正版です.NET 配列のオーバーヘッド?

明らかに、32 ビットと 64 ビットで実行する必要があります。

このオーバーヘッドに追加する必要があるのは、配列の要素 (so size * sizeof(element)) と、少なくとも必要な配列への参照 (so IntPtr.Size) です。

私が気づいたいくつかの矛盾があることに注意してください。double[1]単一の double の配列を作成すると、それぞれが 8 バイト境界に完全に整列しますが、使用されるスペースは 20 バイト/配列 (32 ビットの場合、12 + sizeof(double)) にすぎないようです)。20 は 8 で割り切れないため、これは明らかに不可能GC.GetTotalMemoryです。 オブジェクト間の穴を「無視」していると思います。これは、配列の要素のタイプに応じて、いくつかのバイト/配列の追加のオーバーヘッドになる可能性があります。中サイズの場合byte[1]、配列あたり 16 バイトです (32 ビットの場合、12 + sizeof(byte) + 3)。これはより正しいようです。

于 2013-08-31T17:56:09.213 に答える