Garbage Management: Java vs Go

4 min readDec 26, 2022

Content table for blog

  • Introduction to blog.
  • what is Garbage Collection/Collector?
  • How GC operates.
  • Java’s GC
  • Golang’s GC.
  • Links to resources

Welcome to yet another blog on the internet about Golang, but don’t worry I won’t say pick Golang because it has optimised garbage collection, rather let’s understand what this statement means. Since we call ourselves software developers let’s do the DFS about the infamous Garbage Collection in Golang.

can this beast on Channel steroid beat the garbage?

What is Garbage Collection/Collector?

Assume you write code; to implement it, a specific procedure is called, and it is given a specific amount of RAM. What happens next? The function or code that has completed its task has reserved memory in RAM until it is deleted, resulting in a memory leak/memory overflow.

But, surely, we can free the memory? Yes, we can, and we can make mistakes and blow things off in the process (“the intern brought down the prod again”). This was an issue with boomers like C and C++, but GenZ Go and evergreen Java made their garbage collector automatic. As a result, users face less of a burden.
This is referred to as Garbage Collector (GC).

Inside of memory heap using GC

This is a multi-layer procedure generally followed to filter things and pass them to the next phase where they’re filtered less frequently.

In the first generation, temporary variables are deleted and memory is sent for the second generation, objects that have been used and aren’t used anymore or are no more needed are thus deleted it's less used than in the first.

In the third or the last stage, objects exist till they’re not needed, this is a long-lived stage and runs the least frequently.

To make it simple, 1st gen, if anything is left promote it to 2nd gen, and if anything is left send it to 3rd gen. This is the overall structure inside.

How Java handled its garbage

Java does a similar thing by dividing memory into three parts: Eden, S0 and S1. Initially, memory is kept in Eden space, then to S0, then to S1(S for survivor). Here the frequency of GC is the same in all three layers after a variable gets past these three layers, it's sent to the old generation, where GC runs slowly (less frequently).

Golang’s GC

It is a mark-sweep GC, meaning it works in the sweep and mark phase. To simplify, mark the target(marking phase), sweep it or clean it(sweeping phase) and sleep phase(to be re-run since can’t be kept active always) after a while.

Well, this was the difference, and since I haven’t used Java ever and am a Golang fan, let’s jump in to understand the Go GC deeply.

A tale of two Heaps

Heaps don’t lie, Go is smart and thus keeps two heaps in its GC, one to see what is used in memory(which is left after GC was used), another being used to store functions that were allocated in the new cycle(which can be removed by GC later).

The frequency at which GoGC incur trades between the GC CPU and Memory, Meaning? If the frequency is more, then more CPU cost, less frequency less CPU cost.

To maintain this tradeoff we determine the target heap size after each GC cycle, a target value for the total heap size in the next cycle.

The GC’s goal is to finish a collection cycle before the total heap size exceeds the target heap size. Total heap size is defined as the live heap size at the end of the previous cycle, plus any new heap memory allocated by the application since the previous cycle. Meanwhile, target heap memory is defined as:

Target heap memory = Live heap + (Live heap + GC roots) * GOGC / 100

So this was what goes inside the GC in Golang. A lot can be explored and I can go deeper of course, but my target was to make things descriptive till the point we understand the mechanism.

And since I don’t know much about Java can’t go deep in there.

Fun fact before Go 1.18, Go had only counted the live heap. Often, the amount of memory in goroutine stacks is quite small and the live heap size dominates all other sources of GC work, but in cases where programs had hundreds of thousands of goroutines, the GC was making poor judgements. Thus came the tale of two Heaps.

Links which helped me write:

Thanks for support