|
|
|
|
|
by mananaysiempre
1033 days ago
|
|
A “complete”—i.e. functioning—tracing GC is a weekend project. (Mark-sweep, mark-compact, or stop-and-copy, take your pick.) Perhaps not as simple as basic unoptimized reference counting, but still not hard. The hard part, the one that has occupied JVM engineers for almost three decades now, comes afterwards: when you try to make things not freeze when memory is low, or when you have multiple threads mutating the same heap, or ultimately when you’re adapting the GC to the particulars of your language. (E.g. Haskell has an awesome concurrent GC that’d work like crap for Java, because it assumes tons of really short-lived, really small garbage and almost no mutation. The other way around is also bound to be problematic—I don’t know how the Scala people do it.) So a GC being tracing and not refcounting is not really a useful benchmark. And Go’s GC is undeniably less advanced than OpenJDK’s, simply because almost every other GC is. It can still suit Go’s purposes, but it does mean running Java on top of it is bound to yield interesting results. (And can we please stop pretending C and C++ are in any way close as languages? Even if the latter reuses some parts from the former’s runtime.) |
|
Java relies very heavily on its GC and tends to generate a lot more short lived objects which need collection than Go. Go's approach to memory management learns from this and focuses on creating fewer short-lived memory objects and providing much shorter GC pauses than Java. It's definitely less complex than Java's GC but it's also very performant and a lot less trouble than Java's GC in my experience.