&gt; This article is a great read!<p>Thanks! Glad you enjoyed it!<p>&gt; The article makes it seem as though once you had a valid theoretical model implementation was actually easy, is that true?<p>Rust&#x27;s affine type system is a huge win here. It has a no-surprises approach to handling data, so it&#x27;s very easy to practically track roots and all.<p>So yeah; the implementation is not much more complex than the design above (I don&#x27;t think I skip any nontrivial part of the design in the post, though that is purely by accident -- I intended to give a sketch of the design and the whole design just happened to come out)<p>&gt; What is the disadvantage of the way you do it now?<p>Think of manual rooting as akin to Rc or shared_ptr wrt cost; and the llvm thing is Box&#x2F;unique_ptr.<p>Just how the compiler inserts deterministic alloc&#x2F;free calls with Box, the compiler keeps track of stack based gcthings in llvm. All of the dynamic checks above for rooting become unnecessary; instead at mark time you just pick up the roots from the stack frames. (Note: I haven&#x27;t looked into the llvm feature; I don&#x27;t know if it works this way).<p>Tracking roots is something a compiler is good at. Not so much a runtime.<p>Regarding Java and Go: I don&#x27;t know; I haven&#x27;t tried. But the applications are different -- Java is pervasive, and Go is pervasive with value types and escape analysis (also default concurrent). Rust-gc will probably be horrible at pervasive GCing. Besides, the other two have compiler support so have it much easier when they want to track roots. You can statically insert unconditional  calls to `roots.push(var)` if you own the compiler, but as a library author you can have to keep track of many things at runtime to determine if something is a root (which is why llvms solution looks promising to me). In rust-gcs case, rooting status is stored by all the other existing gcptrs, and the status is changed conditionally depending on their states and interaction.