Someone familiar with the GC internals explained that the GC scales poorly, with total collection time increasing quadratically in function of the amount of memory allocated. That I should be implementing my own custom memory allocation strategies because garbage collectors were always going to be slow. They generate a function's Abstract Syntax Tree (AST) and it's Intermediate Representation (IR), allocating all node objects into a zone, and then discard all of these objects at once when they are no longer needed.