-
Notifications
You must be signed in to change notification settings - Fork 1
Description
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 ois the reference pointing to that object. Objects are allocated in the heap andopoints to the object.
https://youtu.be/H0DeuoIbyrs?t=349
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.
https://youtu.be/H0DeuoIbyrs?t=1579
The new operation
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
ctorwith 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
.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,
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.
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.
Arrays with objects.
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
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()










