Whay is the size of MonoBehaviour instance?

I can’t find a way to access the size(in bytes) of the managed C# objects.

What i would like to know specifically, is how much an instance of monobehaviour takes, and how much of that memory is added when you create your own MonoBehaviour-subclass instance?

Well generally the size of a managed class is just the sum of it’s fields + “some overhead”. While the sum of the fields could be determined by enumerating all fields of a type the “overhead” can’t be specified exactly as it’s not necessarily constant. First of all you have to define what you consider part of the object. For example if an object has an array, that array is a seperate object. A string value is also a seperate object. So the bare class itself is rather small.

Each managed class instance has some generic overhead which however depends on the systems architecture (32 / 64 bit) and the actual implementation of the CLR for the target system. Running the same code and using the same classes on different systems can result in different sizes. Memory address alignment can also play a role. Generally on 32 bit systems the fix overhead for a class instance is 8 bytes and on 64 bit 16. However this is just the overhead. The minimum size is actually 12 bytes on 32 bits and 24 bytes on 64 bit (even an empty class).

The MonoBehaviour class itself as well as Behaviour and Component do not have any fields on their own. However the UnityEngine.Object base class does have 3 fields. One IntPtr, one int and one string variable. IntPtr and string require just the defaut reference / pointer size (so 4 bytes on 32 bit and 8 bytes on 64bit system). An “int” which is just an alias for System.Int32 is always 32 bits (4 bytes). So just looking at the size of the plain managed object instance it’s at least 8 + 4 + 4 +4 == 20 bytes on 32 bit systems and 16 + 4 + 8 + 8 == 36 bytes on 64 bit systems.

So we talk about a class like this:

public class MyMonoBehaviour : MonoBehaviour
{
}

No extra fields or anything. Though that’s not the end of the story. Those 20 / 36 bytes is just the plain managed object. However every component has a native counter part which is basically referenced by the internal IntPtr field in UnityEngine.Object. We don’t know what exactly will be stored in the native part as it’s closed source and part of the engines core. Though every UnityEngine.Object has a name. It doesn’t need to be set to anything but you would require at least one pointer. Each instance has a hideflags int field. The Behaviour class implements an enabled field on the native side. The Component native part has at least a pointer to the owner (gameobject). Also it seems UnityEngine.Object has two additional pointers to manage prefab references. However it’s possible that those only exists in the editor.

Note that we only considered direct fields of the managed class itsef or it’s native counter part. We haven’t included any child objects which you may want to consider to be part of the object (composition). This would include string data for the name and maybe some other internal things. The native part of a MonoBehaviour also has a reference to the script asset that defines the managed class.

All in all you have to calculate with an actual memory (native + managed) of something between 70 and 200 bytes. Though memory alignment and memory allocation by the managed memory manager would make it difficult to give exact numbers.

I also don’t fully understand this part:

[ … ]and how much of that memory is added [ … ]

When an object instance is created all required memory is allocated. But again, only the direct memory usage of the class itself. For example consider this class

public class MyMonoBehaviour : MonoBehaviour
{
    private int[] someValues = new int[100];
    private string test = "Hello World";
}

This class now has an array and a string field. An array as well as a string is a seperate object and does not “belong” to the MyMonoBehaviour class. By adding those fields the size of the class itself will grow by 8 bytes on 32 bit and by 16 bytes on 64 bit systems. However the actual array instance also requires memory. Specifically for arrays of value types it’S the usual 8 byte overhead + 4 bytes length + the size of an element multiplied by the length of the array. So about 12+100*4==412 bytes. Strings work similar but as far as i remember they have some weird 4 byte alignment going on. A string is an array of chars. A char is 16 bit (2 bytes)

So in the example above if we attach this script to a gameobject we have the size of the class itself (which as i said we can’t really determine exactly) + the array instance + the string instance.

The main question is: Why is it that important? What do you want to do?

Are you looking for the sizeof keyword?