It's not a generational GC. This makes the mark-and-sweep phase of every collection more time consuming than it needs to be.
It uses a stop-the-world approach, which means all threads are stopped during the mark phase.
I've had some app that created a lot of short-lived strings (I'm talking many millions here), and profile traces showed it spending almost 20% of its time in the GC, of which nearly 10% in the mark function (which means that for 10% of the apps execution
times, all threads were suspended). That, plus the time taken to allocate all those string objects, meant I got a nearly 40% performance improvement by switching to a custom, mutable string class (I didn't use StringBuilder for reasons that aren't important
right now) so I could reuse the object instances.
A proper generational GC is apparently being worked on but Mono's own people estimate it could be years before it's stable enough to move into the main branch, by which time I hope to have graduated.