Title: CSharp / MemoryManagement

Q: What are the problems with a Mark and Sweep Garbage Collector?::
A: - A mark and sweep GC has to mark all live objects on the heap during each collection cycle.
- This can lead to long program freezes while the collection is running
- Also: repeatedly marking the same objects over and over in each cycle is very inefficient.

Q: How does a Generational Garbage Collector help reduce the problems of a Mark and Sweep Garbage Collector?::
A: - Generations help to reduce the number of objects in gen 0.
- Gen 1 and Gen 2 are collected much less frequently.
- The GC assumes that any object that reaches gen2 must be a long living object that does not need to be checked very often.

Q: What are the Implicit assumptions that the garbage collector operates on?
A: - Objects are either short-lived or long-lived.
- Short-lived objects will be allocated and discarded within a single collection cycle.
- Objects that survive two collection cycles are long-lived.
- 90% of all small objects are short-lived.
- All large objects (85K+) are long-lived.

Q: Which objects remain in the Gen0 list after every garbage collection cycle?
A: Gen 0 is completely cleared i.e. empty.

Q: When optimizing code for GC, what are the two considerations you must look for with regards to object size and lifetime?
A: - Avoid large short-lived objects
- Avoid small long-lived objects

Q: If you have a large short-lived object, what is the one optimization you can try?
A: If you have a large object like say a db connection and for some reason it is short-lived then one optimization that you can use to convert it to a long-lived object is to to pool it in an object pool and reuse it the next time.

Q: Should a finalizer process other referenced objects?
A: A finalizer must only process its own object and never other referenced objects.

Q: You have some referenced objects in your class, will you process them in a finalizer?
A: No. A finalizer must only process its own object and never other referenced objects.

Q: In what order are objects finalized?
A: You cannot make any assumptions about the order in which your objects will be finalized.

Q: Why must you never use a referenced object in finalizer?
A: You should never try to use a referenced object in your finalizer, because it might already be finalized.

Q: In which generation are finalizers always executed?
A: Finalizers always execute in gen1. So, the lifetime of your object will span 2 generations i.e 2 collection cycles.

Q: Are finalizers guaranteed to be called?
A: Finalizers are not guaranteed to be called.

Q: What happens to objects that have not been finalized yet when the host process exits?
A: If the host process exits, anything remaining in the finalization queue after 4 seconds is discarded.

Q: What are finalizers?
A: Finalizers are class methods that are called when objects are about to be cleaned up by the garbage collector.

Q: Why is it bad to have many short-lived objects with finalizers?
A: Many small short-lived objects with finalizers are bad, because the finalizer extends their lifetime into gen1.

Q: Is it a good idea to release scarce resources in a finalizer?
A: No because the time interval between the object creation and the finalizer running could be used.
The resource could be kept allocated for a long time.
Finalizer only runs in gen1. Dispose disposes in gen 0.

Q: Why is it better to use the Dispose method instead of a finalizer to discard scarce resources?
A: - The time interval between the object creation and the finalizer running could be used.
- Finalizer only runs in gen1. Dispose disposes in gen 0.

Q: What does the dispose pattern provide?
A: The dispose pattern provides a method for explicitly releasing scarce resources.

Things to keep in mind while optimizing your code:-
- Avoid boxing and unboxing.
- Do not concatenate strings
- Use structs instead of classes.
- Always pre-size collections.

Things to remember about structs:-
- Assigning structs copies the value of all internal fields.
- Structs can implement interfaces but cannot inherit.
- Structs cannot have instance field intializers.
- Structs cannot have a parameterless constructor.
- Structs cannot have finalizers.

Use cases for structs:-
- Use structs when the data you are storing represents a single value.
- Use structs if your data size is very small (24 bytes or less) and you are going to create thousands or millions of instances.
- Use structs if your data is immutable.
- Use structs if your data will not have to be boxed frequently

Q: What is boxing and unboxing?
A: Boxing and Unboxing is a process that lets you use value types and reference types interchangeably in your code.

Q: What does a boxing operation do?
A: It converts a value type to a reference type.

Q: Where is the output object of a boxing operation stored - stack or heap?
A: Each boxing operation creates one new object on the heap.

Q: Which object is greater in size - a boxed object or its original value type?
A: A boxed object occupies more memory than the original value type.

Q: What are structs?
A: Structs are value types

Q: Why is it advisable to always pre-size collections?
A: Every collection and list in .NET starts out with a certain default capacity, and when it runs out of space it will create a new list of twice the size and copy everything over.

Q: What are the three standard rules of object disposal?
-  [reactivation].
-  [dispose error]
-  [container and child]
A: After an object has been disposed, it cannot be reactivated; Calling an object's Dispose method repeatedly causes no error.; A container object automatically disposes its child objects.

Q: Into how many generation does a GC divy its objects?
A: The GC divides objects into three generations.

Q: What type of objects does the GC collect more frequently?
A: Gen0 and Gen1

Q: What is a root?
A: A root is something that keeps an object alive.

Q: When is an object eligible for garbage collection?
A: When an object is not directly or indirectly referenced by a root, it is eligible for garbage collection.

Q: What are the three types of roots?
A: - A local variable/parameter in an executing method.
- A static variable.
- An object on the queue that stores objects ready for finalization.

Q: When does a finalizer execute?
A: Just before an object is released from memory.

Q: What are the various phases of a garbage collector?
A: - Objects without finalizers are immediately deleted.
- Objects with pending finalizers are put on a queue.
- Garbage collection is complete and the program continues executing.
- A finalizer thread starts running in parallel.
- The finalizer methods of the objects in the finalizer queue are executed.
- The objects are then dequeued.
- The dequeued objects will be deleted in the next collection.

Q: What sort of GC does the standard CLR use?
A: It uses a generational mark and compact GC.

Q: When does the CLR initiate a garbage collection?
A: When the new keyword is called and a memory threshold has been reached.

Q: Can you manually initiate a Garbage Collection?
A: Yes by calling System.GC.Collect.

Q: Can all threads be frozen during a GC?
A: Yes all threads can be frozen.

Q: What does the GC do in the marking step?
A: It marks all objects that can be reached from the root.

Q: What does the GC do in the compact phase?
A: The remaining objects are shifted to the start of the heap(compacted).

Q: What is the purpose of the compaction phase?
A: - New objects can easily be allocated at the end of the heap.
- It prevents memory fragmentation.

Q: What is a Large Object Heap (LOH)?
A: Stores objects larger than 85,000 bytes.

Q: Why should we keep large objects on the LOH and not in Gen0 or Gen1 or Gen2 collections?
A: - As these are large objects, compacting them is an expensive operation making Gen0, Gen1 and Gen2 collections slower.
- Also as they are large objects, they fill up the memory threshold faster making the GC collect more often.
- For these reasons, it is better to move them to another heap like the LOH.

Q: Why is LOH not subject to compaction?
A: Because moving large objects during garbage collection would be expensive.

Q: What are the implications of an LOH not being compacted?
A: Slower Allocation and Fragmentation

Q: How can you manually instruct the GC to compact the LOH?
A: `GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;`

Q: In what generation of the GC is the LOH stored?
A: The LOH is non generational.

Q: What are the 2 garbage collection modes provided by the .NET CLR?
A: Workstation and server are the two garbage collection modes provided by the .NET CLR.

Q: How can you switch to Server GC mode?
A: `<PropertyGroup><ServerGarbageCollection>true</ServerGarbageCollection></PropertyGroup>`

Q: What is the difference between the Server GC and the Workstation GC?
A: Server GC - allocates a separate heap and a separate GC to each core.

Q: In what type of systems is a Server GC only available on?
A: On multicore systems.

Q: What is the background GC feature offered by the CLR?
A: The GC must freeze execution threads during a collection. A background gc minimizes these freezes.

Q: How can you enable Background collection?
A: ```
<PropertyGroup>
    <ConcurrentGarbageCollection>false</ConcurrentGarbageCollection>
</PropertyGroup>
```

Q: Can you manually start garbage collections for only a specific generation?
A: Yes you pass an int value to `GC.Collect` representing the generation to collect.

Q: What is the most common reason for memory leaks in a managed language?
A: Event Handlers.

Q: What is the other most common reason for memory leaks in a managed language?
A: `System.Timers`

Q: How can you manually obtain the current memory consumption of a program's objects?
A: `GC.GetTotalMemory(true)`. It returns a 'long'.