I use dotMemory to profile my application, and I noticed the behavior below: there are some points inside my code when I do the garbage collection manually using
GC.Collect();
GC.WaitForPendingFinalizers();
Inside dotMemory, I see that the memory is actually freed up at these points, but if after that I press "Force GC", then more garaging is going to. How do they do it and why was this memory not collected by my code, and is it possible to achieve the same level of collection?
I am attaching a screenshot where you can see that gene 2 is almost twice reduced by dotMemory 
I also tried to execute several collections, i.e.
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
and although it seems like it is returning a bit more memory, it never comes close to how dotMemory does