This one caught the team at work this week; after having in the past had many reports of "memory leaks" that turned out to be nothing more than the GC twiddling its thumbs while gigabytes of trash accumulated.
Symptom: Intermittent errors, in retail builds only, for some flavours of input, where threads just died; but the code looked sane.
A lot of painful debugging later got us to a method that looked like (stripped to the essentials):
which looks pretty innocent.
And it works most of the time -- until
foo.CreateBar doesn't return immediately. And at that point the fact that
foo becomes eligible for finalization just as soon as the call to
foo.CreateBar begins rises up to bite you, because you're now in a race with the GC. Notably, this is not like C++ where destruction happens only when control leaves the enclosing scope, and that is why it took a long time to figure out what was going on.
Knowing that this can happen, the point of all those odd GC related types and methods suddenly becomes apparent.