What is the minimum size of an object in memory?

Asked

Viewed 193 times

15

I received an answer in my question that talks about a overhead that the object has. Every object has this overhead?

An object without data also has this overhead?

Exists object of size 0?

1 answer

15


The overhead only occurs in types by reference. In types by value it never occurs, it is only the cost of the same object. At least not the overhead header.

Every object is subject to alignment (class organization). So each allocation needs to be multiple of one word. In 64 bits it should always be every 16 bytes. So if the object has 25 bytes, it actually has 32 bytes.

If you are a reference type you will always have a two-word header.

One is the type indicator of the object. It is important for the garbage collector, to know about polymorphism, cast, reflection, etc..

The other word is called syncblock which is usually used to indicate where a monitoring object is in shared objects between threads.

Since it is not so common to use it, it can be used for other things. One of these things is to cache the hash code of the object.

It is also used by GC to make its control during the mark of what is still alive or not.

OBJECTS WITH need an external reference and this space is used for this.

May still contain the ID of AppDomain in some cases.

But there’s a catch. No object has less than 12 bytes in 32 bits, or 24 bytes in 64 bits. The object must have at least one word of "object state", even if it is empty. But if you have an object with a word, this cost is not added, it continues with 12 or 24 bytes in size.

So not only does an object by reference have this overhead, but he has one more overhead if it is empty or less than a word.

Types by reference cannot have size 0 according to the above. Types by value occupy at least 1 byte. This can be checked with:

using System;

class Program {
    static void Main() {
        var memoriaAnterior = GC.GetTotalMemory(true);
        Console.WriteLine(memoriaAnterior);
        var array = new None[1000000];
        var memoriaAtual = GC.GetTotalMemory(true);
        Console.WriteLine(memoriaAtual);
        Console.WriteLine($"Diferença: { memoriaAtual - memoriaAnterior }");
        Console.WriteLine(array.Length);
    }
}

struct None {}

Behold working in the ideone. And in the .NET Fiddle. Also put on the Github for future reference.

To understand a little more: How "free()" knows how much memory has to free?

Note that all of this depends on implementation. There are several implementations of CLR. We can see a different way.

  • 1

    Every time I read a post of yours, I encourage myself to study more, I see that you have mastery over all the subjects addressed.

  • @Diegofarias thanks, but I miss a lot still. I just learned something I didn’t know creating that answer.

  • My goodness, I’m trying to keep up with the content as much as I can, and even reading the answers on the forum, I’ve learned a lot, we’re learning all the time.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.