The JVM inside a container
Modern JVMs read the cgroup limits, so the defaults are sane - until someone hardcodes -Xmx.
Open this lesson in the learning hubKey points
- Since Java 10 the VM reads the cgroup memory and cpu limits, not the whole machine.
UseContainerSupportis on by default. - With no flags the heap is a quarter of the container limit, which leaves three quarters unused. That is usually far too cautious.
- Prefer
-XX:MaxRAMPercentage=75to a fixed-Xmx. It follows the limit when somebody edits the deployment. availableProcessors()follows the cpu quota, and that number sizes the common pool, the GC threads and most client libraries.- A cpu limit of 0.5 rounds up to one processor, so the VM picks the Serial collector and single-threaded defaults all round.
- Check what it really saw:
java -XX:+PrintFlagsFinal -versionrun inside the image, not on your laptop.
Example
import com.sun.management.HotSpotDiagnosticMXBean;
import com.sun.management.VMOption;
import java.lang.management.ManagementFactory;
public class Main {
static final String[] FLAGS = {
"UseContainerSupport", "MaxRAMPercentage", "MaxHeapSize", "UseG1GC", "UseSerialGC"
};
public static void main(String[] args) {
Runtime rt = Runtime.getRuntime();
System.out.println("what this JVM believes it has been given:");
System.out.println(" availableProcessors : " + rt.availableProcessors()
+ " (follows the cpu quota, and sizes the common pool and the GC)");
System.out.println(" max heap : " + (rt.maxMemory() >> 20) + " MB");
System.out.println();
HotSpotDiagnosticMXBean diag =
ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
System.out.println("and where each of those numbers came from:");
for (String flag : FLAGS) {
try {
VMOption opt = diag.getVMOption(flag);
System.out.printf(" %-20s = %-14s origin: %s%n",
flag, opt.getValue(), opt.getOrigin());
} catch (IllegalArgumentException e) {
System.out.printf(" %-20s not present - this one only exists on Linux%n", flag);
}
}
System.out.println();
System.out.println("origin DEFAULT means nobody set it and the VM worked it out itself.");
System.out.println("Inside a 1 GB container with no flags that is a 256 MB heap: a");
System.out.println("quarter of the limit, and three quarters of the memory unused.");
}
}
Set MaxRAMPercentage, not -Xmx, and let the JVM read the limit.
This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the JVM course, and every lesson in it is listed on the JVM contents page.