Visit Azul.com Support

Decoupling a CRaC Image from Host-Specific Settings

Need help?
Schedule a consultation with an Azul performance expert.
Contact Us

In some scenarios, you create a checkpoint on a host that differs significantly from the restore host. For example, you may create the checkpoint in a downsized CI/CD pipeline and restore the image on a production host with many CPU cores and a large amount of memory. In other situations, the checkpoint host may be arbitrary while the application runs in restricted cloud instances.

One aspect of this separation is CPU Features. The JVM also makes other decisions during startup and stores them in the image.

The number of CPU cores is the simplest setting to tune. You can override the number of cores that the JVM can "see" with -XX:ActiveProcessorCount=<N>. Runtime.availableProcessors() reports this value. The JVM uses it to scale GC threads and certain contended structures. CRaC does not resize this value dynamically after restore, so set it before checkpoint to match the system where you restore the CRaC image.

The maximum size of the Java Heap is fixed during the boot time. By default, the JVM on the checkpoint host sizes it to 25% of (RAM size || cgroups memory limit). At that point, the restore host is still unknown. This default may also be too conservative for a container with a single JVM process. Consider the available memory on both the checkpoint host and the restore host, and set the maximum heap size (-Xmx) explicitly.

If the checkpoint host has fewer resources than the restore host, you can temporarily restrain heap growth before checkpoint with -XX:CRaCMaxHeapSizeBeforeCheckpoint=…​. Set the maximum heap size to a value suitable for the restore host, and apply the restraint in the checkpoint environment:

 
java -Xmx32G \ -XX:CRaCMaxHeapSizeBeforeCheckpoint=2G \ -XX:CRaCCheckpointTo=/path/to/image \ -cp ...

The heap does not grow beyond the 2 GB threshold before the checkpoint. After restore, the restraint no longer applies.