Generational Shenandoah Offers Java a Faster Way to Collect Garbage
At its re:Invent annual user conference earlier this month, AWS introduced a variant of an open source Shenandoah garbage collector as a preview in version 17 of of its distribution of the OpenJDK, Corretto. Shenandoah was originally developed by Red Hat, but a recent “generational mode” of the algorithm from the two companies have improves throughput and cuts pause times considerably.
“We believe it is the next step forward garbage collection for the Java Virtual Machine, said Ken Exner, Amazon Web Services general manager of developer tools, who, in a joint presentation with Emily Freeman, AWS head of DevOps marketing, introduced the technology.
“It is the first of its kind a concurrent generational garbage collector for the JVM,” he said.
The new garbage collector has increased efficiency, Exner explained, because it focuses just the most likely places where the garbage exists in memory, thereby reducing the amount of time it pauses an application to do its clean-up chores.
This technique holds great promise not only for Java but for other languages running on the Java Virtual Machine, such as Kotlin, Clojure and Scala.
Java has always had automatic memory management. Periodically, the stock JVM garbage collector goes through memory to find those discarded variables and other bits in the object graph that are no longer referenced by the program and delete them, freeing up memory. It was revolutionary in its day: this automation offers an advantage over older languages such as C and C++, where developers had to de-allocate memory by hand that was no longer being used, the failure to do so would lead to security vulnerabilities.
“What did one garbage collector say to the other garbage collector? … Long pause” — Emily Freeman
The downside to Java’s automatic memory management is considerable, however: In order to sort what can and can not be thrown away, the garbage collector must pause all program threads entirely to sweep through the memory. This makes the language unsuitable for some time-sensitive mission-critical tasks and slows down large Java apps.
To reduce downtime pauses, Shenandoah introduces a new technique called generational garbage collection, the presenters explained. It works on the generational hypothesis, which is basically the assumption, that in most cases, younger objects are more often discarded than older ones.
“Generational Shenandoah identifies the areas that contain new objects from objects that already survived at least one garbage collection suite,” Exner explained. The objects are split into two generations — young and old — and then sweeps through the young objects more frequently.
“Because the collector can focus on the areas that contain the most garbage it lowers pause times, shortens collection cycles, and reduces the amount of memory needed to achieve low pause times,” Exner said. In tests detailed in an AWS blog, the new generational-based Shenandoah was able to reduce pause times to below an almost undetectable 10ms in most cases, with less than a 5% overall application throughput.
According to a recent study from New Relic, there are a number of low-latency garbage collection algorithms being developed. In addition to Shenandoah, there are also contenders such as ZGC, CMS and G1.