Mapping the Heap to HugeTLB
Java applications — Elasticsearch, Cassandra, Kafka, Hadoop — allocate a large contiguous heap at startup. This heap is an ideal candidate for HugePages because it is one large block of memory accessed constantly by the garbage collector and application threads.
JVM flags for HugePages: two flags added to JVM startup arguments do the work — -XX:+UseLargePages tells the JVM to request HugeTLB-backed memory for the heap, and -XX:LargePageSizeInBytes=2m specifies the page size, which must match what the OS has allocated.
The startup crash trap: Unlike Postgres, which can fall back gracefully, the JVM with -XX:+UseLargePages will crash immediately at startup — with an "unable to allocate memory for object heap" error — if the HugeTLB pool does not have enough pages. This happens because the JVM tries to allocate the entire heap (-Xmx) from the HugeTLB pool at startup. If vm.nr_hugepages is set to exactly the right number, a small discrepancy (due to OS overhead or fragmentation) causes the crash.
Safe sizing for Java: Always over-provision by at least 5% — for a 16GB heap, that's 8,192 pages needed, rounded up to roughly 8,700 once the buffer is applied, set the same way as before via vm.nr_hugepages.
Verifying Java is using HugePages: once the JVM is running, a non-zero AnonHugePages count in that process's smaps confirms it landed on huge pages.
Interviewers sometimes ask: "You enabled HugePages for your Elasticsearch cluster but the JVM crashes on startup. What do you check?" Walk through: (1) grep HugePages_Total /proc/meminfo — is the pool large enough? (2) Is the pool fragmented — did the kernel allocate fewer pages than requested? (3) Does the OS user running Elasticsearch have permission to use HugeTLB pages? On some systems, /proc/sys/vm/hugetlb_shm_group must be set to the GID of the application user.