Skip to content

.NET Memory Managment #2

@kidchenko

Description

@kidchenko

https://blog.adamfurmanek.pl/2016/04/23/custom-memory-allocation-in-c-part-1/

.NET do not enforce reference types being stored on the heap.

.NET ECMA Standard, it typically from the head, but not enforce that.

Value types are stored on the heap, but it an value type is part of a reference type it is stored on the heap as well. So value types can be stored anywhere by design. .NET has many implementations we need to consider that we have different implementations.

Object Structure

var o = new object();

What we used to say when we have a line like var o = new object(); is that o is our object, and this is not true it is acceptable - but we want to be more specific. We need to differentiate between the object and the reference, the object is on the right side of the equation, var o is the reference pointing to that object. Objects are allocated in the heap and o points to the object.

https://youtu.be/H0DeuoIbyrs?t=349

image

https://www.codeproject.com/Articles/20481/NET-Type-Internals-From-a-Microsoft-CLR-Perspecti

The size of the object depend of the architecture, it can be 4 bytes or 8 bytes.

One interesting thing is that the object store only the data (the fields). No methods. The methods are stored in somewhere else.

There are other things related with the object, there are something called reflection in .NET that basically says hey which type are you?. This works on runtime every object must to have a tag RTTI address - Runtime Type Information, also know as Execution Engine Class, Type Handle. It because this we can use reflection in .NET we can't do this with reference types they do not have RTTI address. We can call .GetType() in a value object only because we have boxing.

The sync block address. Is used to store details like hash code or locking mechanisms. If it is too big, it a address to another space in the memory that contains that metadata.

GC facts

Facts:

  • There are three generations: 0, 1 and 2
  • Large object heap contains objects having at least 85000 bytes (only?)
  • Large object heap is in generation 2

Questions:
Which generation holds a object on stack? - // gen 2
GC.GetGeneration(valueType)

List

Ordinary list saves a collection of references to objects.

image

https://youtu.be/H0DeuoIbyrs?t=1579

The new operation

https://youtu.be/H0DeuoIbyrs

Allocation - newobj

The newobj instruction:

  • Allocates a new instance of the class associated with ctor()
  • initializes all the fields in the new instance to 0 (of the proper type) or null
  • calls the constructor ctor with the given arguments along with the newly created instance
  • after the constructor has been called, the noew initialized object reference (type O) is pushed on the stack.

Measuring .NET Performance

GC as a performance problem

  • The .NET GC is non-deterministic
  • Contributes to very long delays, that destroy responsiveness
  • There is many flavors (implementation) of GC
  • GC is often missed by traditional profiling

There is no GC if you don't allocate. Reducing allocations is key to reducing GC costs

Reducing allocations

  • Use value types instead value types
  • Pool large objects (such as buffers)
  • Avoid allocation large temporary objects

Memory Fragmentation

  • GC allocates virtual memory in large chunks (segments)
  • When the segment is completely fill the runtime request more
  • Virtual memory can quicly become fragmented when dealing with 32-bit address spaces (2-4GB)
  • Fragmentation can cause a OutOfMemoryException

image

.NET Memory Allocations and Performance

  • Build a mental model to understand performance & .NET Memory Layout
  • Mental model is create a visualization of what happens when we call methods, pass arguments and create instances of objects.
  • Have this mental model help us to have a better understanding of our .NET code

The basics

https://youtu.be/aylUPfOVM90?t=273

  • What is a value type?
  • What is a reference type?
  • What are the differences between Value Types and Reference Types?

Value types are allocate in the stack is partially correct.

When you call a method a stack frame is allocated for that method
If your method call another method

The stack is called stack because it is literary a stack data structure.
This is a single threaded operation,

image

image

image

image

if a struct (value type) contains a reference type, the struct will be allocated on the stack, but the reference type properties will be allocated on the heap and then the struck will have these reference types.

image

Arrays

Question

Arrays are value types or reference types?
All the arrays are reference type

The difference between arrays is that they are keep contiguous. Arrays and string is a special type of data structure.

image

Arrays with objects.

image

About the reference types, the runtime keeps a count to the references to some variable. When the garbage collector has 0 references for that object it knows that it can clean objects.

In .NET allocating objects is very cheap in fact in .NET the allocation of memory is faster than in C++, but we pay the price of the garbage collector latter. So if you allocate to much objects you don't pay for the allocation but pay for the clean up.

.NET Memory Layout

  • What is special about the stack?
  • Why are stack allocations/dealocations faster?
  • If the physical memory is the same, why stack is faster?

When the process start, the the OS allocate a certain chunk of memory, that is your virtual space for memory. And there is a pointer that says: this is the begin of heap and this is the begin of stack. The stack grow upwards and the heap grow downwards.

On the stack the memory moves to a location to another and then clean all the memory. and because it is not managed you don't need to figure out what you need to allocated or dealocate. It is a simply memory location that goes from here to there.

While in the heap the garbage collector need to manage all the objects, and count how many references are there, and if it can clean this memory or that memory.

We don't pay for the time of allocation, we pay for the time of deallocation.

Object Layout Reference Type

https://youtu.be/aylUPfOVM90?t=1862

image

When you have a object, the variable point to a space in the memory. This space in the memory has some structure.

From the location of the address - 4 bytes is the sync block index

pointer to location - 4 bytes = sync block location

The bare minimum size of an object in .NET - a class with no properties is 12 bytes for x86 and 24 for x64.

From the location of the address we have the method table pointer.

Then we have the properties. In the example

  • 4 bytes for id
  • 8 bytes for value
  • 8 bytes for date
  • Pointer to a string (Name)

strings and arrays are special objects.

Method Table

  • Type Object Pointer
  • Base Method Table pointer
    • Object.Equals()
    • Object.GetHashCode()
    • Object.ToString()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions