Here's how Java allocates an object of size N: round N up to a multiple of 8 bytes, and bump the allocation pointer by that much. That's it. By using a scheme called a thread-local heap (TLH), there is no contention between threads. There's some additional handling for large objects, and for the case when the TLH is exhausted and another one must be allocated, but generally speaking, the GC is self-tuning so that none of these activities appear on the hot path of an application. The overhead is generally negligible, and all you're left with is the pointer bump.
What is to stop someone from implementing something like this in a C library? It sounds like it could be relatively easily done... or is it the TLH that causes issues?