Will my object be placed in the Large Object Heap?

340 views Asked by At

When the CLR places an object on the Large Object Heap, is it an "all or nothing" deal? Are class/struct members "split up" and placed in different heaps?

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();

Is TwoSmallObjects placed on the Large Object Heap since its total size is over 85,000 bytes? Even though both members are individually under the threshold? What about MixedSizeObjects?

2

There are 2 answers

0
Phil Wright On BEST ANSWER

Each of the byte arrays that you are allocating are treated separately from the enclosing class. So the OneBigObject is actually two different CLR objects. One is the OneBigObject instance that is very small and contains just a reference field. The other is the actual byte array of 100,000 instances. The same principle applies to the other classes as well.

Classes and structs are not split up. There is no need because it is hard to imagine anyone creating a type that has enough actual fields to make it 85k in storage size. Large looking objects, like your example, actually consist of references and arrays of references and so are not very big at all.

3
svick On

The size of TwoSmallObjects (ignoring the overhead each object has) is just 8 bytes (16 in 64-bit process). Similarly, the size of MixedSizeObjects is just 24 bytes (48 on 64-bit).

So, to answer your question, neither of those objects goes onto the LOH. The arrays they reference might, depending on the size of each individual array.

I can't imagine how would a system that would work the way you expect work. Especially considering that constructor runs after allocating the object. How would the allocator know what are you going to assign to its fields before you actually do that? Should it move the object to LOH if you do that? Why would it do all that work, if it doesn't help anything.

Another thing that might help: if you have a type of a reference type (and an array is one), the field doesn't contain the object. It contains just the reference.