1. memory architecture
2. Generations
- Generation 0: short lived objects (collected frequently)
- Generation 1: Medium lived objects (collected less frequently)
- Generation 2: long lived objects (variable size and expensive to collect)
- Generation 0 and 1 is known as the ephemeral segment (fixed size)
SOS :! Eeheap-GC
Sosex :! Gcgen <address>
3. Roots
- GC uses roots to find which objects are alive or dead
- Any object with an existing reference to it has a root and is thus considered alive
- Roots are determined using the following components: JIT compoler, stack Walker, handle table, finalize queue
SOS :! Gcroot <address>
4. Finalization
- GC only knows about Managed Objects
- Objects that wrap native types need a cleanup Mechanism
- Objects that wrap a native types must:
- Implement a finalizer
- Implement idisposable
- Both methods shocould Use same private helper Method
Finalization Best Practices
- Whenever possible do not rely on finalization rather always explicitly dispose finalizable objects
- If you implement a finalizer you shoshould also implement idisposable (dispose suppresses the object finalization)
- In C #, the using {} pattern automatically invokes the dispose method
5. Large Object heap
- Objects greater than 85,000 bytes
- Key difference is that LOH is not compacted (very common cause of memory fragmentation)
- Introduced to avoid the cost of Compaction
6. Pinning Problems
- As part of compaction the GC may move an object around
- Problem for objects passed to native code (for example, a buffer to async native Operation)
- Pinning tells the GC that it is not allowed to move the object
- Excessive pinning common cause of memory fragmentation