Spring Boot 4.1.1 catalog service measured on JDK 25, 26 and 27: live heap 320 MB to 273 MB with compact headers, per-class bytes per instance, container-sizing sweeps with real cgroup limits, 1-CPU Serial vs G1 with Native Memory Tracking, removed flags (MaxRAM, UseCompressedClassPointers), and a kernel OOM-kill check. Outputs in jdk27-memory/output. Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01TF9JWFvJSNm6HVzswzZU5a
65 lines
2.9 KiB
Bash
Executable File
65 lines
2.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# What each JDK decides by default, and what the flags do. Every line is the JVM's own answer
|
|
# (java -XX:+PrintFlagsFinal), not something inferred from documentation.
|
|
source "$(dirname "$0")/lib.sh"
|
|
|
|
show() { # label jdk flags... (set CG_MEM/CG_CPUS to run inside a container-style cgroup)
|
|
local label="$1" jh="$2"; shift 2
|
|
local out cg=""
|
|
if [ -n "${CG_MEM:-}" ]; then
|
|
cg="fl$$-$RANDOM"; cg_create "$cg" "$CG_MEM" "${CG_CPUS:-2}"
|
|
out=$(bash -c "$CG_JOIN" _ "$cg" "$jh/bin/java" "$@" -XX:+PrintFlagsFinal -version 2>&1)
|
|
cg_remove "$cg"
|
|
else
|
|
out=$("$jh/bin/java" "$@" -XX:+PrintFlagsFinal -version 2>&1)
|
|
fi
|
|
if ! echo "$out" | grep -q 'UseCompactObjectHeaders'; then
|
|
printf '%-52s -> JVM refused to start:\n' "$label"; echo "$out" | head -3 | sed 's/^/ /'; return
|
|
fi
|
|
local ch gc heap
|
|
ch=$(echo "$out" | awk '$2=="UseCompactObjectHeaders"{print $4}')
|
|
gc=$(echo "$out" | awk '($2=="UseG1GC"||$2=="UseSerialGC"||$2=="UseParallelGC"||$2=="UseZGC") && $4=="true"{print $2}' | tr '\n' ' ')
|
|
heap=$(echo "$out" | awk '$2=="MaxHeapSize"{printf "%d", $4/1048576}')
|
|
printf '%-52s -> compact=%-5s collector=%-13s MaxHeapSize=%sMB\n' "$label" "$ch" "$gc" "$heap"
|
|
echo "$out" | grep -E '^(OpenJDK 64-Bit Server VM warning|Error|Unrecognized)' | sed 's/^/ JVM says: /' | head -2
|
|
}
|
|
|
|
for v in 25 26 27; do
|
|
jh_var="JDK$v"; jh="${!jh_var}"
|
|
echo "== JDK $v: $("$jh/bin/java" -version 2>&1 | sed -n 2p)"
|
|
show "default (this machine: 2 CPUs)" "$jh"
|
|
show "-XX:+UseCompactObjectHeaders" "$jh" -XX:+UseCompactObjectHeaders
|
|
show "-XX:-UseCompactObjectHeaders" "$jh" -XX:-UseCompactObjectHeaders
|
|
echo
|
|
done
|
|
|
|
echo "== The same JDKs in a container: 1 GB memory limit, 1 CPU (a cgroup, set the way Docker sets it)"
|
|
for v in 25 26 27; do
|
|
jh_var="JDK$v"; jh="${!jh_var}"
|
|
CG_MEM=$((1024*1024*1024)) CG_CPUS=1 show "JDK $v, 1 GB, 1 CPU" "$jh"
|
|
CG_MEM=$((1024*1024*1024)) CG_CPUS=1 show "JDK $v, 1 GB, 1 CPU, MaxRAMPercentage=75" "$jh" -XX:MaxRAMPercentage=75
|
|
done
|
|
echo
|
|
echo "== 1 GB, 2 CPUs"
|
|
for v in 26 27; do
|
|
jh_var="JDK$v"; jh="${!jh_var}"
|
|
CG_MEM=$((1024*1024*1024)) CG_CPUS=2 show "JDK $v, 1 GB, 2 CPUs" "$jh"
|
|
done
|
|
echo
|
|
|
|
echo "== -XX:MaxRAM: the flag many people used to fake a container limit"
|
|
show "JDK 26 -XX:MaxRAM=1g" "$JDK26" -XX:MaxRAM=1g
|
|
show "JDK 27 -XX:MaxRAM=1g" "$JDK27" -XX:MaxRAM=1g
|
|
echo
|
|
|
|
echo "== Compact headers with each collector on JDK 27"
|
|
for gc in UseG1GC UseParallelGC UseSerialGC UseZGC; do
|
|
show "JDK 27 -XX:+$gc" "$JDK27" -XX:+$gc
|
|
done
|
|
echo
|
|
|
|
echo "== Compressed pointers on JDK 27"
|
|
show "JDK 27 -XX:-UseCompressedClassPointers" "$JDK27" -XX:-UseCompressedClassPointers
|
|
show "JDK 27 -XX:-UseCompressedOops" "$JDK27" -XX:-UseCompressedOops
|
|
show "JDK 27 -Xmx32g (a large explicit heap)" "$JDK27" -Xmx32g
|