From df13a904d7c8ec8e9dc35072d1767fdaa0244191 Mon Sep 17 00:00:00 2001 From: Ankur Mhatre Date: Mon, 12 Oct 2026 17:13:14 +0000 Subject: [PATCH] Add jdk28-zgc: ZGC startup and warmup baseline on JDK 25/27/28-ea, and a probe for JEP 545/546 Spring Boot 4.1.1 harness measuring first-response time versus initial heap size and a 20,000-request warmup. Shows -XX:+ZAdaptiveHeapSizing is not yet in any build. Co-Authored-By: Claude Sonnet 5.5 Claude-Session: https://claude.ai/code/session_01WzVQ6zFh9cuLPj9RSbRH8U --- README.md | 1 + jdk28-zgc/README.md | 78 ++++++++++++++++ jdk28-zgc/output/01-flag-probe.txt | 30 +++++++ jdk28-zgc/output/02-startup-vs-xms.txt | 90 +++++++++++++++++++ jdk28-zgc/output/03-warmup.txt | 24 +++++ jdk28-zgc/pom.xml | 33 +++++++ jdk28-zgc/scripts/Warmup.java | 37 ++++++++ jdk28-zgc/scripts/run-all.sh | 45 ++++++++++ jdk28-zgc/scripts/startup.sh | 32 +++++++ jdk28-zgc/scripts/warmup.sh | 18 ++++ .../java/com/ankurm/zgc/DemoApplication.java | 43 +++++++++ 11 files changed, 431 insertions(+) create mode 100644 jdk28-zgc/README.md create mode 100644 jdk28-zgc/output/01-flag-probe.txt create mode 100644 jdk28-zgc/output/02-startup-vs-xms.txt create mode 100644 jdk28-zgc/output/03-warmup.txt create mode 100644 jdk28-zgc/pom.xml create mode 100644 jdk28-zgc/scripts/Warmup.java create mode 100755 jdk28-zgc/scripts/run-all.sh create mode 100755 jdk28-zgc/scripts/startup.sh create mode 100755 jdk28-zgc/scripts/warmup.sh create mode 100644 jdk28-zgc/src/main/java/com/ankurm/zgc/DemoApplication.java diff --git a/README.md b/README.md index 09a6897..441c513 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,7 @@ the part most "ZGC is faster" posts leave out. | [`jmh/`](jmh/src/main/java/com/ankurm/zgc/jmh) | Throughput and barrier microbenchmarks | JMH 1.37 | | [`jdk27-memory/`](jdk27-memory) | Spring Boot 4.1 service measured on JDK 25, 26 and 27: compact object headers (JEP 534) and G1 everywhere (JEP 523), heap footprint, container sizing with real cgroup limits. Its README and `output/` replace a `docs/` folder; the write-up is [the post](https://ankurm.com/jdk-27-compact-object-headers-g1-default-memory-spring-boot/) | Spring Boot 4.1.1, three JDKs | | [`flags/`](flags) | The flag-by-flag production cheat sheet: `MaxRAMPercentage` vs a hardcoded `-Xmx` (one fails safely, one gets the container SIGKILLed), `-XX:-UseContainerSupport`, the `ActiveProcessorCount` lie, and which diagnostic flags (`HeapDumpOnOutOfMemoryError`, `NativeMemoryTracking`) are worth leaving on in prod — on real Docker containers, JDK 25 and JDK 27. Its README and `docs/output/` replace a `docs/` folder; the write-up is [the post](https://ankurm.com/jvm-flags-for-spring-boot-in-containers-jdk-25-27/) | Spring Boot 4.1.1, Docker, two JDKs | +| [`jdk28-zgc/`](jdk28-zgc) | ZGC startup and warmup versus initial heap size on JDK 25, 27 and 28 early access with a Spring Boot 4.1.1 server, plus a probe showing that JEP 545/546's `-XX:+ZAdaptiveHeapSizing` is not in any build yet. Its README and `output/` replace a `docs/` folder; the write-up is [the post](https://ankurm.com/zgc-jdk-28-adaptive-heap-sizing-faster-startup/) | Spring Boot 4.1.1, three JDKs | ### JMH benchmarks diff --git a/jdk28-zgc/README.md b/jdk28-zgc/README.md new file mode 100644 index 0000000..293a658 --- /dev/null +++ b/jdk28-zgc/README.md @@ -0,0 +1,78 @@ +# jdk28-zgc — what ZGC startup and heap sizing look like today, and what JEP 545 / 546 propose + +Companion module for the ankurm.com post +**ZGC in JDK 28: Adaptive Heap Sizing (JEP 546) and Faster Startup (JEP 545)**. +There is no `docs/` folder: this README and the captured files in [`output/`](output) are the documentation. + +## The honest status + +On 12 October 2026 both JEPs show **"Proposed to Target"** for release 28 on openjdk.org. Neither is integrated. +[`output/01-flag-probe.txt`](output/01-flag-probe.txt) proves it: `-XX:+ZAdaptiveHeapSizing` is an +*Unrecognized VM option* on JDK 25.0.4.1, Temurin 27+35 and OpenJDK 28-ea+19. +So this module does **not** benchmark the proposed features. It measures the baseline they are meant to improve, +on three JDKs, so you can rerun it the day a build contains the flag. + +## Versions + +| Component | Version | +|---|---| +| JDK 25 | Temurin 25.0.4.1+1 (LTS) | +| JDK 27 | Temurin 27+35 (GA 2026-09-15) | +| JDK 28 | OpenJDK 28-ea+19 (jdk.java.net build 19, 2026-10-08) | +| Spring Boot | 4.1.1 (`spring-boot-starter-webmvc`) | +| Machine | 2 vCPU, 8 GB RAM Linux sandbox (a small box: absolute numbers are illustrative) | + +## Quick start + +```console +mvn -B -DskipTests package # build with any JDK 25+ +export J25=/path/to/jdk-25 J27=/path/to/jdk-27 J28=/path/to/jdk-28-ea +scripts/run-all.sh # regenerates everything in output/ +RUNS=10 scripts/run-all.sh # more runs, tighter medians +scripts/startup.sh $J28 "my label" 5 -XX:+UseZGC -Xms1g +``` + +## Files + +| File | What it is | +|---|---| +| [`src/main/java/com/ankurm/zgc/DemoApplication.java`](src/main/java/com/ankurm/zgc/DemoApplication.java) | One server: `/hello` allocates 16 KB, `/heap` reports committed and max heap | +| [`scripts/startup.sh`](scripts/startup.sh) | Wall-clock ms from process start to first HTTP 200, repeated, with min/median/max | +| [`scripts/warmup.sh`](scripts/warmup.sh) + [`scripts/Warmup.java`](scripts/Warmup.java) | 20,000 requests, 4 threads, timing each batch of 2,000; client is always JDK 25 | +| [`scripts/run-all.sh`](scripts/run-all.sh) | Runs all three experiments | + +## Results (median of 5 runs, milliseconds to first response) + +| Config | JDK 25 | JDK 27 | JDK 28-ea | +|---|---|---|---| +| ZGC defaults | 3439 | 3421 | 3420 | +| `-Xms64m` | 3299 | 3276 | 3350 | +| `-Xms1g` | 3478 | 3275 | 3642 | +| `-Xms3g` | 3836 | 3618 | 3803 | +| `-Xms3g -XX:+AlwaysPreTouch` | 4834 | 4560 | 5010 | + +Raw per-run lines: [`output/02-startup-vs-xms.txt`](output/02-startup-vs-xms.txt). + +Warmup, total ms for the first 20,000 requests (first 2,000 in brackets): + +| Config | JDK 25 | JDK 28-ea | +|---|---|---| +| defaults | 9708 (2678) | 9912 (2567) | +| `-Xms3g` | 9193 (2606) | 9608 (2431) | +| `-Xms64m` | 9247 (2442) | 9893 (2590) | + +Raw: [`output/03-warmup.txt`](output/03-warmup.txt). + +## What the numbers say, and do not say + +- A bigger initial heap costs startup time, and `AlwaysPreTouch` costs the most (about +1.2 s to +1.6 s on a 3 GB heap here). +- On this small box the effect is a fraction of Spring Boot's own ~3.3 s startup. JEP 545 describes a much larger effect on big heaps + (about 0.1 s at 2 MB versus over 10 s at 32 GB). This machine cannot reproduce that, and these numbers do not test it. +- The first batch of 2,000 requests takes about 2.4 to 2.7 s in every configuration, so for this app warmup is dominated by JIT and class loading, not heap growth. +- Under ZGC, `InitialHeapSize` ergonomics are 98,566,144 bytes on JDK 25 but 8,388,608 bytes on JDK 27 and 28-ea + ([`output/01-flag-probe.txt`](output/01-flag-probe.txt)). I did not find which change causes that, so the post reports it as an observation only. +- Timings drift between runs. Treat them as indicative, not as a result. + +## Licence + +MIT, as the parent repository. diff --git a/jdk28-zgc/output/01-flag-probe.txt b/jdk28-zgc/output/01-flag-probe.txt new file mode 100644 index 0000000..e63704d --- /dev/null +++ b/jdk28-zgc/output/01-flag-probe.txt @@ -0,0 +1,30 @@ +== JDK 25 +openjdk version "25.0.4.1" 2026-08-18 LTS + size_t InitialHeapSize = 98566144 {product} {ergonomic} + size_t MaxHeapSize = 1568669696 {product} {ergonomic} + size_t SoftMaxHeapSize = 1411802726 {manageable} {ergonomic} + bool ZUncommit = true {product} {default} + uintx ZUncommitDelay = 300 {product} {default} +-- probing -XX:+ZAdaptiveHeapSizing +Unrecognized VM option 'ZAdaptiveHeapSizing' + +== JDK 27 +openjdk version "27" 2026-09-15 + size_t InitialHeapSize = 8388608 {product} {ergonomic} + size_t MaxHeapSize = 1568669696 {product} {ergonomic} + size_t SoftMaxHeapSize = 1411802726 {manageable} {ergonomic} + bool ZUncommit = true {product} {default} + uintx ZUncommitDelay = 300 {product} {default} +-- probing -XX:+ZAdaptiveHeapSizing +Unrecognized VM option 'ZAdaptiveHeapSizing' + +== JDK 28-ea +openjdk version "28-ea" 2027-03-23 + size_t InitialHeapSize = 8388608 {product} {ergonomic} + size_t MaxHeapSize = 1568669696 {product} {ergonomic} + size_t SoftMaxHeapSize = 1411802726 {manageable} {ergonomic} + bool ZUncommit = true {product} {default} + uintx ZUncommitDelay = 300 {product} {default} +-- probing -XX:+ZAdaptiveHeapSizing +Unrecognized VM option 'ZAdaptiveHeapSizing' + diff --git a/jdk28-zgc/output/02-startup-vs-xms.txt b/jdk28-zgc/output/02-startup-vs-xms.txt new file mode 100644 index 0000000..0a5494c --- /dev/null +++ b/jdk28-zgc/output/02-startup-vs-xms.txt @@ -0,0 +1,90 @@ +jdk25 zgc default run 1: first-response 3439 ms, committed heap 156 MiB +jdk25 zgc default run 2: first-response 3596 ms, committed heap 154 MiB +jdk25 zgc default run 3: first-response 3325 ms, committed heap 154 MiB +jdk25 zgc default run 4: first-response 3529 ms, committed heap 154 MiB +jdk25 zgc default run 5: first-response 3251 ms, committed heap 154 MiB +jdk25 zgc default SUMMARY: min 3251 ms, median 3439 ms, max 3596 ms (n=5) +jdk25 zgc Xms64m run 1: first-response 3291 ms, committed heap 158 MiB +jdk25 zgc Xms64m run 2: first-response 3233 ms, committed heap 154 MiB +jdk25 zgc Xms64m run 3: first-response 3299 ms, committed heap 154 MiB +jdk25 zgc Xms64m run 4: first-response 3488 ms, committed heap 156 MiB +jdk25 zgc Xms64m run 5: first-response 3396 ms, committed heap 156 MiB +jdk25 zgc Xms64m SUMMARY: min 3233 ms, median 3299 ms, max 3488 ms (n=5) +jdk25 zgc Xms1g run 1: first-response 3502 ms, committed heap 1024 MiB +jdk25 zgc Xms1g run 2: first-response 3475 ms, committed heap 1024 MiB +jdk25 zgc Xms1g run 3: first-response 3478 ms, committed heap 1024 MiB +jdk25 zgc Xms1g run 4: first-response 3728 ms, committed heap 1024 MiB +jdk25 zgc Xms1g run 5: first-response 3395 ms, committed heap 1024 MiB +jdk25 zgc Xms1g SUMMARY: min 3395 ms, median 3478 ms, max 3728 ms (n=5) +jdk25 zgc Xms3g run 1: first-response 3836 ms, committed heap 3072 MiB +jdk25 zgc Xms3g run 2: first-response 4070 ms, committed heap 3072 MiB +jdk25 zgc Xms3g run 3: first-response 3886 ms, committed heap 3072 MiB +jdk25 zgc Xms3g run 4: first-response 3717 ms, committed heap 3072 MiB +jdk25 zgc Xms3g run 5: first-response 3827 ms, committed heap 3072 MiB +jdk25 zgc Xms3g SUMMARY: min 3717 ms, median 3836 ms, max 4070 ms (n=5) +jdk25 zgc Xms3g pretouch run 1: first-response 5058 ms, committed heap 3072 MiB +jdk25 zgc Xms3g pretouch run 2: first-response 4941 ms, committed heap 3072 MiB +jdk25 zgc Xms3g pretouch run 3: first-response 4801 ms, committed heap 3072 MiB +jdk25 zgc Xms3g pretouch run 4: first-response 4834 ms, committed heap 3072 MiB +jdk25 zgc Xms3g pretouch run 5: first-response 4626 ms, committed heap 3072 MiB +jdk25 zgc Xms3g pretouch SUMMARY: min 4626 ms, median 4834 ms, max 5058 ms (n=5) +jdk27 zgc default run 1: first-response 3598 ms, committed heap 148 MiB +jdk27 zgc default run 2: first-response 3421 ms, committed heap 148 MiB +jdk27 zgc default run 3: first-response 3510 ms, committed heap 148 MiB +jdk27 zgc default run 4: first-response 3280 ms, committed heap 152 MiB +jdk27 zgc default run 5: first-response 3239 ms, committed heap 150 MiB +jdk27 zgc default SUMMARY: min 3239 ms, median 3421 ms, max 3598 ms (n=5) +jdk27 zgc Xms64m run 1: first-response 3276 ms, committed heap 152 MiB +jdk27 zgc Xms64m run 2: first-response 3252 ms, committed heap 146 MiB +jdk27 zgc Xms64m run 3: first-response 3348 ms, committed heap 150 MiB +jdk27 zgc Xms64m run 4: first-response 3479 ms, committed heap 146 MiB +jdk27 zgc Xms64m run 5: first-response 3156 ms, committed heap 152 MiB +jdk27 zgc Xms64m SUMMARY: min 3156 ms, median 3276 ms, max 3479 ms (n=5) +jdk27 zgc Xms1g run 1: first-response 3165 ms, committed heap 1024 MiB +jdk27 zgc Xms1g run 2: first-response 3475 ms, committed heap 1024 MiB +jdk27 zgc Xms1g run 3: first-response 3412 ms, committed heap 1024 MiB +jdk27 zgc Xms1g run 4: first-response 3275 ms, committed heap 1024 MiB +jdk27 zgc Xms1g run 5: first-response 3237 ms, committed heap 1024 MiB +jdk27 zgc Xms1g SUMMARY: min 3165 ms, median 3275 ms, max 3475 ms (n=5) +jdk27 zgc Xms3g run 1: first-response 4142 ms, committed heap 3072 MiB +jdk27 zgc Xms3g run 2: first-response 3846 ms, committed heap 3072 MiB +jdk27 zgc Xms3g run 3: first-response 3618 ms, committed heap 3072 MiB +jdk27 zgc Xms3g run 4: first-response 3563 ms, committed heap 3072 MiB +jdk27 zgc Xms3g run 5: first-response 3593 ms, committed heap 3072 MiB +jdk27 zgc Xms3g SUMMARY: min 3563 ms, median 3618 ms, max 4142 ms (n=5) +jdk27 zgc Xms3g pretouch run 1: first-response 4782 ms, committed heap 3072 MiB +jdk27 zgc Xms3g pretouch run 2: first-response 4560 ms, committed heap 3072 MiB +jdk27 zgc Xms3g pretouch run 3: first-response 4385 ms, committed heap 3072 MiB +jdk27 zgc Xms3g pretouch run 4: first-response 4532 ms, committed heap 3072 MiB +jdk27 zgc Xms3g pretouch run 5: first-response 4623 ms, committed heap 3072 MiB +jdk27 zgc Xms3g pretouch SUMMARY: min 4385 ms, median 4560 ms, max 4782 ms (n=5) +jdk28ea zgc default run 1: first-response 3439 ms, committed heap 144 MiB +jdk28ea zgc default run 2: first-response 3918 ms, committed heap 144 MiB +jdk28ea zgc default run 3: first-response 3290 ms, committed heap 144 MiB +jdk28ea zgc default run 4: first-response 3420 ms, committed heap 146 MiB +jdk28ea zgc default run 5: first-response 3170 ms, committed heap 146 MiB +jdk28ea zgc default SUMMARY: min 3170 ms, median 3420 ms, max 3918 ms (n=5) +jdk28ea zgc Xms64m run 1: first-response 3350 ms, committed heap 146 MiB +jdk28ea zgc Xms64m run 2: first-response 3217 ms, committed heap 148 MiB +jdk28ea zgc Xms64m run 3: first-response 3367 ms, committed heap 148 MiB +jdk28ea zgc Xms64m run 4: first-response 3274 ms, committed heap 150 MiB +jdk28ea zgc Xms64m run 5: first-response 3522 ms, committed heap 150 MiB +jdk28ea zgc Xms64m SUMMARY: min 3217 ms, median 3350 ms, max 3522 ms (n=5) +jdk28ea zgc Xms1g run 1: first-response 3458 ms, committed heap 1024 MiB +jdk28ea zgc Xms1g run 2: first-response 3733 ms, committed heap 1024 MiB +jdk28ea zgc Xms1g run 3: first-response 3478 ms, committed heap 1024 MiB +jdk28ea zgc Xms1g run 4: first-response 3642 ms, committed heap 1024 MiB +jdk28ea zgc Xms1g run 5: first-response 4136 ms, committed heap 1024 MiB +jdk28ea zgc Xms1g SUMMARY: min 3458 ms, median 3642 ms, max 4136 ms (n=5) +jdk28ea zgc Xms3g run 1: first-response 3590 ms, committed heap 3072 MiB +jdk28ea zgc Xms3g run 2: first-response 3871 ms, committed heap 3072 MiB +jdk28ea zgc Xms3g run 3: first-response 3803 ms, committed heap 3072 MiB +jdk28ea zgc Xms3g run 4: first-response 3691 ms, committed heap 3072 MiB +jdk28ea zgc Xms3g run 5: first-response 3857 ms, committed heap 3072 MiB +jdk28ea zgc Xms3g SUMMARY: min 3590 ms, median 3803 ms, max 3871 ms (n=5) +jdk28ea zgc Xms3g pretouch run 1: first-response 5010 ms, committed heap 3072 MiB +jdk28ea zgc Xms3g pretouch run 2: first-response 4882 ms, committed heap 3072 MiB +jdk28ea zgc Xms3g pretouch run 3: first-response 5040 ms, committed heap 3072 MiB +jdk28ea zgc Xms3g pretouch run 4: first-response 5283 ms, committed heap 3072 MiB +jdk28ea zgc Xms3g pretouch run 5: first-response 4764 ms, committed heap 3072 MiB +jdk28ea zgc Xms3g pretouch SUMMARY: min 4764 ms, median 5010 ms, max 5283 ms (n=5) diff --git a/jdk28-zgc/output/03-warmup.txt b/jdk28-zgc/output/03-warmup.txt new file mode 100644 index 0000000..2c69430 --- /dev/null +++ b/jdk28-zgc/output/03-warmup.txt @@ -0,0 +1,24 @@ +== jdk25 zgc default +batch ms: 2678 1147 993 749 829 667 715 591 745 588 +total ms: 9708 +committed after load: 342 MiB (max 1496 MiB) +== jdk25 zgc Xms3g +batch ms: 2606 1155 909 958 748 674 546 409 637 548 +total ms: 9193 +committed after load: 3072 MiB (max 3072 MiB) +== jdk25 zgc Xms64m +batch ms: 2442 1221 971 810 997 689 648 548 480 437 +total ms: 9247 +committed after load: 312 MiB (max 1496 MiB) +== jdk28ea zgc default +batch ms: 2567 1217 977 979 907 826 730 590 602 512 +total ms: 9912 +committed after load: 284 MiB (max 1496 MiB) +== jdk28ea zgc Xms3g +batch ms: 2431 1282 1112 947 716 709 651 631 566 559 +total ms: 9608 +committed after load: 3072 MiB (max 3072 MiB) +== jdk28ea zgc Xms64m +batch ms: 2590 1182 1076 886 796 704 779 717 561 598 +total ms: 9893 +committed after load: 414 MiB (max 1496 MiB) diff --git a/jdk28-zgc/pom.xml b/jdk28-zgc/pom.xml new file mode 100644 index 0000000..a84ea0e --- /dev/null +++ b/jdk28-zgc/pom.xml @@ -0,0 +1,33 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 4.1.1 + + + com.ankurm + jdk28-zgc + 1.0.0 + jdk28-zgc + Startup and heap-sizing harness for ZGC across JDK 25, 27 and 28 early access + + 25 + + + + org.springframework.boot + spring-boot-starter-webmvc + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/jdk28-zgc/scripts/Warmup.java b/jdk28-zgc/scripts/Warmup.java new file mode 100644 index 0000000..d2ba4d8 --- /dev/null +++ b/jdk28-zgc/scripts/Warmup.java @@ -0,0 +1,37 @@ +import java.net.URI; +import java.net.http.*; +import java.util.*; +import java.util.concurrent.*; +import java.util.concurrent.atomic.*; + +/** Fires TOTAL requests with THREADS threads and reports how long each batch of BATCH took. */ +public class Warmup { + public static void main(String[] a) throws Exception { + int port = Integer.parseInt(a[0]); + int total = 20_000, batch = 2_000, threads = 4; + HttpClient c = HttpClient.newBuilder().version(HttpClient.Version.HTTP_1_1).build(); + HttpRequest rq = HttpRequest.newBuilder(URI.create("http://localhost:" + port + "/hello")).build(); + AtomicInteger done = new AtomicInteger(); + long[] batchEnd = new long[total / batch]; + long t0 = System.nanoTime(); + ExecutorService ex = Executors.newFixedThreadPool(threads); + List> fs = new ArrayList<>(); + for (int t = 0; t < threads; t++) fs.add(ex.submit(() -> { + try { + while (true) { + int n = done.incrementAndGet(); + if (n > total) return null; + c.send(rq, HttpResponse.BodyHandlers.discarding()); + if (n % batch == 0) batchEnd[n / batch - 1] = System.nanoTime(); + } + } catch (Exception e) { throw new RuntimeException(e); } + })); + for (Future f : fs) f.get(); + ex.shutdown(); + StringBuilder sb = new StringBuilder("batch ms:"); + long prev = t0; + for (long e : batchEnd) { sb.append(' ').append((e - prev) / 1_000_000); prev = e; } + System.out.println(sb); + System.out.println("total ms: " + (prev - t0) / 1_000_000); + } +} diff --git a/jdk28-zgc/scripts/run-all.sh b/jdk28-zgc/scripts/run-all.sh new file mode 100755 index 0000000..f1e40d7 --- /dev/null +++ b/jdk28-zgc/scripts/run-all.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +# Regenerates every file in output/. Set J25, J27, J28 to the three JDK home directories. +# Timing results drift between runs and machines; treat them as indicative, not exact. +set -u +HERE="$(cd "$(dirname "$0")" && pwd)" +OUT="$HERE/../output"; mkdir -p "$OUT" +: "${J25:?}" "${J27:?}" "${J28:?}" +export JDK_CLIENT="$J25" +RUNS=${RUNS:-5} + +# 01 - what does each JDK say about the ZGC flags the two JEPs talk about? +{ + for p in "25|$J25" "27|$J27" "28-ea|$J28"; do + v=${p%%|*}; h=${p#*|} + echo "== JDK $v" + "$h/bin/java" -version 2>&1 | grep -v Picked | sed -n 1p + "$h/bin/java" -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -XX:+PrintFlagsFinal -version 2>&1 \ + | grep -E ' (InitialHeapSize|MaxHeapSize|SoftMaxHeapSize|ZUncommit|ZUncommitDelay) ' | sed 's/ \{2,\}/ /g' + echo "-- probing -XX:+ZAdaptiveHeapSizing" + "$h/bin/java" -XX:+UseZGC -XX:+ZAdaptiveHeapSizing -version 2>&1 | grep -v Picked | sed -n 1p + echo + done +} > "$OUT/01-flag-probe.txt" + +# 02 - startup versus initial heap size +{ + for p in "jdk25|$J25" "jdk27|$J27" "jdk28ea|$J28"; do + l=${p%%|*}; h=${p#*|} + "$HERE/startup.sh" "$h" "$l zgc default" "$RUNS" -XX:+UseZGC + "$HERE/startup.sh" "$h" "$l zgc Xms64m" "$RUNS" -XX:+UseZGC -Xms64m + "$HERE/startup.sh" "$h" "$l zgc Xms1g" "$RUNS" -XX:+UseZGC -Xms1g + "$HERE/startup.sh" "$h" "$l zgc Xms3g" "$RUNS" -XX:+UseZGC -Xms3g + "$HERE/startup.sh" "$h" "$l zgc Xms3g pretouch" "$RUNS" -XX:+UseZGC -Xms3g -XX:+AlwaysPreTouch + done +} > "$OUT/02-startup-vs-xms.txt" 2>&1 + +# 03 - warmup: how long do the first 20,000 requests take? +{ + for p in "jdk25|$J25" "jdk28ea|$J28"; do + l=${p%%|*}; h=${p#*|} + "$HERE/warmup.sh" "$h" "$l zgc default" -XX:+UseZGC + "$HERE/warmup.sh" "$h" "$l zgc Xms3g" -XX:+UseZGC -Xms3g + "$HERE/warmup.sh" "$h" "$l zgc Xms64m" -XX:+UseZGC -Xms64m + done +} > "$OUT/03-warmup.txt" 2>&1 diff --git a/jdk28-zgc/scripts/startup.sh b/jdk28-zgc/scripts/startup.sh new file mode 100755 index 0000000..60ce355 --- /dev/null +++ b/jdk28-zgc/scripts/startup.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +# Usage: startup.sh