aarondwi.github.io

View the Project on GitHub

Java VS Go GC

Java does generational memory management. Creating objects do not call malloc, instead just use from already malloc large buffer. This malloc’ed buffer periodically (or when reaching mmeory limit) cleaned, compacted during the GC. No fragmented memory. Allocation is cheap and blazing fast, as every allocations are just like allocations on stack, but longer GC pause to move memory between, at least until ZGC/Shenandoah in JDK 16/17, where every steps in the GC can be done concurrently. This also why in JVM world object pooling not so popular.

Go does not use generational or any kind, but a variant of Concurrent mark-and-sweep. Non compacting, so they can’t just use large buffer, cause gonna be wasteful, and instead is a malloc. So allocation is expensive, but can get smaller GC pause (less work as there is no need moving between generation, etc). Also use escape analysis to allocate on stack as most as possible. This is why object pooling is popular, beside reducing malloc cost, also reduce fragmentation.

Few discussions

  1. Here and its HN thread
  2. This SO thread