1. What happens to small objects?
Small .NET objects are allocated onto the Small Object Heaps (SOH). There are three of these: Generation 0, Generation 1, and Generation 2. Objects move up these Generations based on their age.
New objects are placed on Gen 0. When Gen 0 becomes full, the .NET Garbage Collector (GC) runs, disposing of objects which are no longer needed and moving everything else up to Gen 1. If Gen 1 becomes full the GC runs again, but also moves objects in Gen 1 up to Gen 2.
A full GC run happens when Gen 2 becomes full. This clears unneeded Gen 2 objects, moves Gen 1 objects to Gen 2, then moves Gen 0 objects to Gen 1, and finally clears anything which isn't referenced. After each GC run, the affected heaps are compacted, to keep memory which is still in use together.
This generational approach keeps things running efficiently – the time-consuming compacting process only occurs when absolutely necessary.
Note: if you see a high proportion of memory in Gen 2, it's an indicator that memory is being held onto for a long time, and that you may have a memory problem. This is where a memory profiling tool, such as ANTS Memory Profiler, can come in handy.