Size of A Class (object) in .NET

后端 未结 6 930
灰色年华
灰色年华 2020-11-28 09:31

How to determine if a Class in .NET is big or small? Is it measured on how many it\'s attributes or fields, datatype of its attributes/fields? or return type of methods? par

相关标签:
6条回答
  • 2020-11-28 09:52

    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.

    0 讨论(0)
  • 2020-11-28 09:56

    While the following article is old (.NET 1.1), the concepts explain clearly what the CLR is doing to allocate memory for objects instantiated in your application; which heaps are they placed in, where their object reference pointers are addressing, etc.

    Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects

    0 讨论(0)
  • 2020-11-28 09:57

    There's a project on github called dotnetex that uses some magic and shows the size of a class or object.

    Usage is simple:

    GCex.SizeOf<Object>();    // size of the type
    GCEx.SizeOf(someObject);  // size of the object;
    

    Under the hood it uses some magic.
    To count size of a type it casts pointer of method table to internal MethodTableInfo struct and uses it's Size property like this:

    public static unsafe Int32 SizeOf<T>()
    {
        return ((MethodTableInfo *)(typeof(T).TypeHandle.Value.ToPointer()))->Size;
    }
    

    To count size of an object it uses true dark magic that quite hard to get :) Take a look at the code.

    0 讨论(0)
  • 2020-11-28 10:12

    In general, a class is larger when it has many instance (non-static) fields, regardless of their value; classes have a memory minimum of 12 bytes and fields with reference types are 4 bytes on 32-bit systems and 8 bytes on 64-bit systems. Other fields may be laid out with padding to word boundaries, such that a class with four byte fields actually may occupy four times 4 bytes in memory. But this all depends on the runtime.

    Don't forget about the fields that may be hidden in, for example, your automatic property declarations. Since they are backed by a field internally, they'll add to the size of the class:

    public string MyProperty
    { get; set; }
    

    Note that the following property has no influence on the class size because it isn't backed by a field:

    public bool IsValid
    { get { return true; } }
    

    To get an idea of the in-memory size of a class or struct instance: apply the [StructLayout(LayoutKind.Sequential)] attribute on the class and call Marshal.SizeOf() on the type or instance.

    [StructLayout(LayoutKind.Sequential)]
    public class MyClass
    {
        public int myField0;
        public int myField1;
    }
    
    int sizeInBytes = Marshal.SizeOf(typeof(MyClass));
    

    However, because the runtime can layout the class in memory any way it wishes, the actual memory used by an instance may vary unless you apply the StructLayoutAttribute.

    0 讨论(0)
  • 2020-11-28 10:12

    When one says class size, I would assume that it means how many members the class has, and how complex the class is.

    However, your question is the size of the memory required when we are creating instance of class. We cannot be so sure about exact size, because .Net framework preserves and keeps the underlying memory management away from us (which is a good thing). Even we have the correct size now, the value might be correct forever. Anyway, we can be sure that the following will take some space in the memory:

    1. Instance variable.
    2. Automatic property.

    So that makes sense to say that User class will take more memory than Member class does.

    0 讨论(0)
  • 2020-11-28 10:18

    You can also check: how-much-memory-instance-of-my-class-uses. There is easy way to test size of object after constructor is called.

    0 讨论(0)
提交回复
热议问题