Notes on Java's new Z Garbage Collector

Jayan Kandathil

First published

The new experimental garbage collector in Java 11 named ZGC is available only on Linux x86_64. Its main attraction is that GC pause times do not increase with heap size, and it is NUMA-aware.

Here's a level 200 video about it, and a more detailed level 300 video.

See blog entry by [Dominik Inf├╝hr] (A First Look into ZGC), and [Sadiq Jaffer & Richard Warburton] (Java's new Z Garbage Collector (ZGC) is very exciting). Also see this thread on the r/java subreddit.

Some preparatory steps are required if you want to test this in a big way:

Since it is supposed to benefit from Linux's huge (2 MB) memory pages, create them with:
echo 67584 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
Then verify that they have been created (1 GB is 512 pages, so 67,584 pages is 132 GB)
cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
Raise the system limit on number of memory mappings per process. Edit /etc/sysctl.conf and add the following line (Heap in MB x 1.8):
Reload the config
sysctl -p
Verify that the change took
cat /proc/sys/vm/max_map_count
Increase the maximum number of processes available to a single user:
ulimit -u unlimited
Increase the maximum number of open file descriptors:
ulimit -n 1000000

Since this is an experimental feature, you have to enable it with the -XX:+UnlockExperimentalVMOptions argument. All said and done, here is the command I ended up using:

 nohup /mnt/ephemeral0/jdk-11.0.1/bin/java -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -Xmx128G -Xms128G -XX:ParallelGCThreads=12 -XX:ConcGCThreads=12 -XX:+AlwaysPreTouch -XX:+UseLargePages -verbosegc -Xlog:gc* -Xlog:gc:gc.log -jar ProcessRequestLog.jar &

I performed a couple of experiments on an AWS z1d.6xlarge instance using RHEL 7.6, OpenJDK 11 and a multi-threaded AEM request.log parser I had written. As you can see from this AWS CloudWatch chart, the ZGC did not perform significantly better than G1GC, at least for the workload I used. Note that the first signature represents the test with ZGC. The AEM request.log had about 500,000 lines in it.

You should see messages such as below at the start:

[0.004s][info][gc,init] Initializing The Z Garbage Collector
[0.004s][info][gc,init] Version: 11.0.1+13 (release)
[0.004s][info][gc,init] NUMA Support: Disabled
[0.004s][info][gc,init] CPUs: 24 total, 24 available
[0.004s][info][gc,init] Memory: 191137M
[0.004s][info][gc,init] Large Page Support: Enabled (Explicit)
[0.004s][info][gc,init] Workers: 12 parallel, 12 concurrent
[0.005s][info][gc,init] Heap backed by file: /dev/hugepages/java_heap.28701
[0.006s][info][gc,init] Available space on backing filesystem: N/A
[0.006s][info][gc,init] Pre-touching: Enabled
[0.006s][info][gc,init] Pre-mapping: 131016M
[25.858s][info][gc,init] Runtime Workers: 12 parallel
[25.859s][info][gc ] Using The Z Garbage Collector