Size of a Class (Object) in .Net

Size of A Class (object) in .NET

The size of a class instance is determined by:

  • The amount of data actually stored in the instance
  • The padding needed between the values
  • Some extra internal data used by the memory management

So, typically a class containing a string property needs (on a 32 bit system):

  • 8 bytes for internal data
  • 4 bytes for the string reference
  • 4 bytes of unused space (to get to the minimum 16 bytes that the memory manager can handle)

And typically a class containing an integer property needs:

  • 8 bytes for internal data
  • 4 bytes for the integer value
  • 4 bytes of unused space (to get to the minimum 16 bytes that the memory manager can handle)

As you see, the string and integer properties take up the same space in the class, so in your first example they will use the same amount of memory.

The value of the string property is of course a different matter, as it might point to a string object on the heap, but that is a separate object and not part of the class pointing to it.

For more complicated classes, padding comes into play. A class containing a boolean and a string property would for example use:

  • 8 bytes for internal data
  • 1 byte for the boolean value
  • 3 bytes of padding to get on an even 4-byte boundary
  • 4 bytes for the string reference

Note that these are examples of memory layouts for classes. The exact layout varies depending on the version of the framework, the implementation of the CLR, and whether it's a 32-bit or 64-bit application. As a program can be run on either a 32-bit or 64-bit system, the memory layout is not even known to the compiler, it's decided when the code is JIT:ed before execution.

How to find the size of a class in C#

Short answer:

You dont.

Long answer:

You can only do that if you type has a fixed layout and has no managed members. Structs are fixed by default. Classes can attributed to have a fixed layout.

(I am not showing how, as you really do not need it. It is only important when doing interop.)

Size of a simple class containing a single integer property in .NET

Marshal.SizeOf(Type) returns the size of the equivalent unmanaged type, i.e. how many bytes would the equivalent unmanaged type (e.g. a C++ class) take if it had the same field layout and packing. Note that this function is designed to work only with classes with the [StructLayout] attribute with a LayoutKind of either Explicit or Sequential.

The memory used up when the CLR allocates an object on the managed heap depends on the internals of the CLR in question. Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects is an article about the CLRv2 implementation of object allocation. Essentially, every object has two hidden fields - a sync block index and a type handle. The sync block is an internal structure used when an object is used with a lock(obj) {} statement. The type handle provides runtime type information about the given instance - it contains the object's method table, etc.

How to get Size of a object (class, structure) in c#

You cant get size of object if you dont use unsafe coding (marshal)

You can use a tool like:

CLR Profiler

VSTS Profiler

.NET Memory Profiler

C# Object Size Overhead

Typically, there is an 8 or 12 byte overhead per object allocated by the GC. There are 4 bytes for the syncblk and 4 bytes for the type handle on 32bit runtimes, 8 bytes on 64bit runtimes. For details, see the "ObjectInstance" section of Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects on MSDN Magazine.

Note that the actual reference does change on 32bit or 64bit .NET runtimes as well.

Also, there may be padding for types to fit on address boundaries, though this depends a lot on the type in question. This can cause "empty space" between objects as well, but is up to the runtime (mostly, though you can affect it with StructLayoutAttribute) to determine when and how data is aligned.

.NET Object size

4 byte boundaries on x86. Possibly 8 byte boundaries on x64.

There's an 8 byte overhead on x86, for a type reference and a sync block. I wouldn't be surprised to find that's 12 or 16 bytes on x64.

For some reason, on x86 an instance of just System.Object appears to take 12 bytes, making 12 bytes the absolute minimum size possible - but a class with an int also takes 12 bytes. I've no idea why this is the case.

How big is an object reference in .NET?

The reference itself is basically a pointer. 32 bits on a 32 bit OS, 64 bits on a 64 bit OS.

The size of the object that's referenced is more complicated.

Why is the size of an empty class not zero in C#?

  • "0" takes up some space itself to store - if you store it as a 4 byte number it takes up 4 bytes!
  • Of course this information about the class has to take up memory otherwise where would you read it from?

A C# "class" as defined on MSDN

A class is a construct that enables you to create your own custom types by grouping together variables of other types, methods and events. A class is like a blueprint. It defines the data and behavior of a type. If the class is not declared as static, client code can use it by creating objects or instances which are assigned to a variable. The variable remains in memory until all references to it go out of scope. At that time, the CLR marks it as eligible for garbage collection. If the class is declared as static, then only one copy exists in memory and client code can only access it through the class itself, not an instance variable.

.NET object size limit

.NET limits any object to max 2 GB even on 64 bit platforms. You can create your own data type, that uses multiple objects to store more data, thus getting around the 2 GB limit of a single object. For instance a List<float[]> would allow you to store more than 2 GB, but you would have to write the necessary plumbing code to make it behave similar to a single, large array.

You may also want to check this question.



Related Topics



Leave a reply



Submit