#!/usr/bin/env bash # Linux / macOS equivalent of run-all.ps1. # # ./scripts/run-all.sh /path/to/jdk-25 [measureSeconds] [warmupSeconds] # # Everything published in the companion blog post came from the PowerShell version on Windows; # this script produces the same set of files in results/ so the comparison can be repeated on # server hardware, which is where you should actually make a decision. set -euo pipefail JAVA_HOME_ARG="${1:-${JAVA_HOME:-}}" MEASURE_SECONDS="${2:-60}" WARMUP_SECONDS="${3:-20}" if [[ -z "$JAVA_HOME_ARG" ]]; then echo "usage: $0 /path/to/jdk-25 [measureSeconds] [warmupSeconds]" >&2 exit 2 fi ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" JAVA="$JAVA_HOME_ARG/bin/java" JAVAC="$JAVA_HOME_ARG/bin/javac" OUT="$ROOT/out" RESULTS="$ROOT/results" LOGS="$ROOT/logs" mkdir -p "$OUT" "$RESULTS" "$LOGS" # Fixed heap: -Xms == -Xmx removes heap resizing as a variable. HEAP=(-Xms2g -Xmx2g) STALL_HEAP=(-Xms512m -Xmx512m) echo "==> compiling" mapfile -t SOURCES < <(find "$ROOT/latency/src" "$ROOT/tuning/src" "$ROOT/internals/src" "$ROOT/analysis/src" -name '*.java') "$JAVAC" -d "$OUT" "${SOURCES[@]}" capture() { local name="$1"; shift echo "==> $name" "$@" > "$RESULTS/$name.txt" 2>&1 || true tail -n 4 "$RESULTS/$name.txt" | sed 's/^/ /' } capture 01-env-zgc "$JAVA" -XX:+UseZGC "${HEAP[@]}" "$ROOT/env/Env.java" capture 01-env-g1 "$JAVA" -XX:+UseG1GC "${HEAP[@]}" "$ROOT/env/Env.java" capture 02-flags-zgc "$JAVA" -XX:+UseZGC "${HEAP[@]}" -XX:+PrintFlagsFinal -version capture 02-flags-g1 "$JAVA" -XX:+UseG1GC "${HEAP[@]}" -XX:+PrintFlagsFinal -version capture 03-latency-zgc "$JAVA" -XX:+UseZGC "${HEAP[@]}" \ "-DwarmupSeconds=$WARMUP_SECONDS" "-Dseconds=$MEASURE_SECONDS" \ "-Xlog:gc*,gc+heap=debug:file=$LOGS/zgc-latency.log:time,uptime,level,tags" \ -cp "$OUT" com.ankurm.zgc.latency.LatencyHarness capture 03-latency-g1 "$JAVA" -XX:+UseG1GC "${HEAP[@]}" \ "-DwarmupSeconds=$WARMUP_SECONDS" "-Dseconds=$MEASURE_SECONDS" \ "-Xlog:gc*,gc+heap=debug:file=$LOGS/g1-latency.log:time,uptime,level,tags" \ -cp "$OUT" com.ankurm.zgc.latency.LatencyHarness capture 04-stalls-zgc-baseline "$JAVA" -XX:+UseZGC "${STALL_HEAP[@]}" -Dseconds=20 \ -cp "$OUT" com.ankurm.zgc.tuning.AllocationStallDemo capture 04-stalls-zgc-softmax "$JAVA" -XX:+UseZGC -XX:SoftMaxHeapSize=400m "${STALL_HEAP[@]}" -Dseconds=20 \ -cp "$OUT" com.ankurm.zgc.tuning.AllocationStallDemo capture 04-stalls-zgc-spiketolerance "$JAVA" -XX:+UseZGC -XX:ZAllocationSpikeTolerance=5 "${STALL_HEAP[@]}" -Dseconds=20 \ -cp "$OUT" com.ankurm.zgc.tuning.AllocationStallDemo capture 04-stalls-g1 "$JAVA" -XX:+UseG1GC "${STALL_HEAP[@]}" -Dseconds=20 \ "-Xlog:gc:file=$LOGS/g1-stress.log:time,uptime" \ -cp "$OUT" com.ankurm.zgc.tuning.AllocationStallDemo capture 05-pages-zgc "$JAVA" -XX:+UseZGC "${HEAP[@]}" -cp "$OUT" com.ankurm.zgc.internals.PageSizeDemo capture 05-pages-g1 "$JAVA" -XX:+UseG1GC "${HEAP[@]}" -cp "$OUT" com.ankurm.zgc.internals.PageSizeDemo capture 06-gclog-zgc "$JAVA" -cp "$OUT" com.ankurm.zgc.analysis.GcLogParser "$LOGS/zgc-latency.log" capture 06-gclog-g1 "$JAVA" -cp "$OUT" com.ankurm.zgc.analysis.GcLogParser "$LOGS/g1-latency.log" echo "==> building JMH module" (cd "$ROOT/jmh" && JAVA_HOME="$JAVA_HOME_ARG" mvn -q -B clean package) # NOTE: the GC flag MUST be inside -jvmArgs. JMH forks a fresh JVM per trial and does not inherit # flags from the outer `java -jar` command. See docs/06-methodology.md section 6.6. for gc in UseZGC UseG1GC; do tag=$([[ "$gc" == "UseZGC" ]] && echo zgc || echo g1) capture "07-jmh-$tag" "$JAVA" -jar "$ROOT/jmh/target/benchmarks.jar" \ -jvmArgs "-XX:+$gc -Xms2g -Xmx2g" -prof gc -rf json -rff "$RESULTS/07-jmh-$tag.json" done echo echo "All raw output is in $RESULTS"