Skip to content

Commit d27c1aa

Browse files
wezellclaude
andauthored
feat(container): auto-tune JVM GC algorithm in setenv.sh based on available vCPUs (#36259)
## Summary - Replaces the static `JAVA_OPTS_MEMORY` GC config with CPU-aware auto-selection at container startup - 1–3 vCPUs → G1GC (default) + `G1PeriodicGCInterval=10000` to return memory to OS on idle - 4+ vCPUs → `-XX:+UseZGC` (Java 25 GenerationalZGC by default; sub-millisecond pauses, scales with cores) - SerialGC explicitly excluded — not appropriate for a long-running multi-threaded web server ## Details CPU detection uses `nproc` with `/proc/cpuinfo` fallback; defaults to 2 if neither is available. Base memory flags (`MaxRAMPercentage=72.0`, heap free ratios, NIO buffer cap) are unchanged. Set `JAVA_OPTS_MEMORY` before startup to bypass auto-selection entirely. Follows the same cgroup-aware pattern already used by `JAVA_OPTS_DIRECT`. ## Test plan - [ ] Verify startup log prints `setenv: auto-GC: ...` with detected vCPU count - [ ] On a 1-vCPU container (or `nproc` returning 1–3), confirm `G1PeriodicGCInterval` appears in JVM flags (`-XX:+PrintFlagsFinal` or `jcmd <pid> VM.flags`) - [ ] On a 4+-vCPU container, confirm `-XX:+UseZGC` / GenerationalZGC is active - [ ] Set `JAVA_OPTS_MEMORY="-XX:MaxRAMPercentage=60.0"` and confirm auto-tune block is skipped - [ ] Confirm no regression in startup time or heap usage on standard containers Closes #36258 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 4ac6ea6 commit d27c1aa

1 file changed

Lines changed: 17 additions & 2 deletions

File tree

  • dotCMS/src/main/resources/container/tomcat9/bin

dotCMS/src/main/resources/container/tomcat9/bin/setenv.sh

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,23 @@ export LANG=${LANG:-"C.UTF-8"}
55

66
export JAVA_OPTS_BASE=${JAVA_OPTS_BASE:-"-Djava.awt.headless=true -Djava.library.path=/usr/lib/$( uname -m )-linux-gnu/ -XX:+UseCompactObjectHeaders --enable-preview "}
77

8-
# This is what MS jaz always runs. G1GC is now java default
9-
export JAVA_OPTS_MEMORY=${JAVA_OPTS_MEMORY:-"-XX:MaxRAMPercentage=72.0 -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=50 -XX:G1PeriodicGCInterval=10000 -Djdk.nio.maxCachedBufferSize=262144"}
8+
# Auto-tune GC algorithm based on available vCPUs:
9+
# 1-3 cores → G1GC (default) + G1PeriodicGCInterval to return memory to OS on idle
10+
# 4+ → ZGC (Java 25 uses GenerationalZGC by default; sub-ms pauses, scales with cores)
11+
# Override by setting JAVA_OPTS_MEMORY before this script runs.
12+
if [ -z "${JAVA_OPTS_MEMORY+set}" ]; then
13+
_cpus=$(nproc 2>/dev/null || grep -c '^processor' /proc/cpuinfo 2>/dev/null || echo 2)
14+
_mem_base="-XX:MaxRAMPercentage=72.0 -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=50 -Djdk.nio.maxCachedBufferSize=262144"
15+
16+
if [ "$_cpus" -le 3 ]; then
17+
_gc="-XX:G1PeriodicGCInterval=10000"
18+
else
19+
_gc="-XX:+UseZGC"
20+
fi
21+
22+
export JAVA_OPTS_MEMORY="$_mem_base $_gc"
23+
echo "setenv: auto-GC: ${_gc} (${_cpus} vCPU; override via JAVA_OPTS_MEMORY)"
24+
fi
1025

1126
# Calculate direct (off-heap) buffer memory based on container memory to prevent unbound growth
1227
# can't use a percentage here so we have to calc it ourselves

0 commit comments

Comments
 (0)