2

CLRがオブジェクトをラージオブジェクトヒープに配置する場合、それは「オールオアナッシング」取引ですか?クラス/構造体のメンバーは「分割」され、異なるヒープに配置されていますか?

class OneBigObject
{
    byte[] bigObject;

    public OneBigObject()
    {
        bigObject = new byte[100000];
    }
}

class TwoSmallObjects
{
    byte[] smallObject1;
    byte[] smallObject2;

    public TwoSmallObjects()
    {
        smallObject1 = new byte[50000];
        smallObject2 = new byte[50000];
    }
}

class MixedSizeObjects
{
    byte[] smallObject1;
    byte[] smallObject2;
    byte[] bigObject;

    public MixedSizeObjects()
    {
        smallObject1 = new byte[50000];
        smallObject2 = new byte[50000];
        bigObject = new byte[100000];
    }
}

OneBigObject oneBigObject = new OneBigObject();
TwoSmallObjects twoObjects = new TwoSmallObjects();
MixedSizeObjects mixedSizeObjects = new MixedSizeObjects();

TwoSmallObjects合計サイズが85,000バイトを超えるため、ラージオブジェクトヒープに配置されますか?両方のメンバーが個別にしきい値を下回っていても?どうMixedSizeObjectsですか?

4

2 に答える 2

3

割り当てている各バイト配列は、囲んでいるクラスとは別に扱われます。したがって、OneBigObject は実際には 2 つの異なる CLR オブジェクトです。1 つは、参照フィールドのみを含む非常に小さい OneBigObject インスタンスです。もう 1 つは、100,000 インスタンスの実際のバイト配列です。同じ原則が他のクラスにも適用されます。

クラスと構造体は分割されません。ストレージ サイズを 85k にするのに十分な実際のフィールドを持つ型を作成する人を想像するのは難しいため、その必要はありません。あなたの例のように、大きく見えるオブジェクトは、実際には参照と参照の配列で構成されているため、それほど大きくはありません。

于 2011-10-25T01:28:24.077 に答える
1

のサイズTwoSmallObjects(各オブジェクトのオーバーヘッドを無視) はわずか 8 バイト (64 ビット プロセスでは 16 バイト) です。同様に、 のサイズMixedSizeObjectsはわずか 24 バイトです (64 ビットでは 48 バイト)。

したがって、あなたの質問に答えるために、これらのオブジェクトはどちらも LOH にはなりません。それらが参照する配列は、個々の配列のサイズによって異なる場合があります。

期待どおりに機能するシステムがどのように機能するか想像できません。特に、オブジェクトの割り当て後にコンストラクターが実行されることを考慮してください。アロケーターは、実際にそれを行う前に、フィールドに何を割り当てるかをどのように知るのでしょうか? その場合、オブジェクトをLOHに移動する必要がありますか? 何も役に立たないのに、なぜそれがすべての仕事をするのでしょうか。

役立つかもしれないもう 1 つのこと: 参照型の型がある (そして配列が 1 つである) 場合、フィールドにはオブジェクトが含まれません。参照のみが含まれています。

于 2011-10-25T01:26:40.050 に答える