Demo Walkthrough

Step-by-step guide through all 9 demos. Demos 01-03 are the core set for a 60-minute talk. Demos 04-09 are bonus material for extended sessions.

Before you begin: Complete the Getting Started guide. All commands assume you're in the spring-boot-demos/ directory.

Demo 01: Container-Aware Heap Sizing

Core 5 min Java 21

Learning Objective

Understand why the JVM reads host RAM by default and how UseContainerSupport + MaxRAMPercentage=75 fixes the mismatch.

Steps

  1. Navigate: cd demo-01-heap-sizing
  2. Run: ./demo.sh
  3. Observe the "bad" container — JVM sees host RAM, claims a huge heap, and gets OOMKilled
  4. Observe the "good" container — JVM reads cgroup limits, sets heap to ~75% of the 512 MB container limit
  5. Note the jcmd output showing the heap sizes in both scenarios

What to Look For

Key Takeaway

Never hardcode -Xmx/-Xms in containers. Use -XX:MaxRAMPercentage=75.0 so the JVM dynamically sizes the heap to the container's memory limit.

Demo 02: GC Monitoring with Prometheus & Grafana

Core 10 min Spring Boot 4.0.5 Podman Compose

Learning Objective

See GC behavior in real time via Micrometer + Prometheus + Grafana. Understand why percentiles-histogram.jvm.gc.pause=true is essential.

Steps

  1. Navigate: cd demo-02-gc-monitoring
  2. Start the stack: ./demo.sh (starts Spring Boot app + Prometheus + Grafana via podman-compose)
  3. Open Grafana: http://localhost:3000 (admin/admin)
  4. Navigate to the JVM dashboard (pre-provisioned)
  5. Generate GC pressure:
    curl "http://localhost:8080/allocate?mb=50"
    curl "http://localhost:8080/allocate?mb=100"
  6. Watch the GC pause histogram update in Grafana
  7. Test virtual threads:
    curl "http://localhost:8080/threads?count=500"
  8. Stop the stack: podman-compose down

What to Look For

Key Takeaway

Two dependencies (spring-boot-starter-actuator + micrometer-registry-prometheus) and three lines of application.properties give you full JVM observability. The histogram property is the most commonly missed piece.

Demo 03: AppCDS Startup Acceleration

Core 5 min Spring Boot 4.0.5 3-stage build

Learning Objective

See the 35-55% startup reduction from AppCDS, understand the 3-stage Containerfile pattern, and learn why Spring Boot benefits more from CDS than build-time frameworks.

Steps

  1. Navigate: cd demo-03-appcds
  2. Run: ./demo.sh
  3. The script builds two images: baseline (no CDS) and optimized (with AppCDS archive)
  4. Compare the startup times printed in the output
  5. Note the 3-stage Containerfile: builder → CDS trainer → runtime

What to Look For

Key Takeaway

Spring Boot's runtime class loading is its Achilles' heel for startup — and that's exactly what AppCDS caches. The more classes your app loads, the bigger the CDS win. This is a Containerfile-only change with zero application code modifications.

Demo 04: Project Leyden AOT Cache

Bonus 5 min JDK 25

Learning Objective

Understand the Project Leyden workflow for Spring Boot: explicit -XX:AOTMode=record and -XX:AOTMode=create steps in a 3-stage Containerfile.

Steps

  1. Navigate: cd demo-04-leyden
  2. Run: ./demo.sh (builds with eclipse-temurin:25 in the container)
  3. Observe the three build stages: compile → train (record + create) → runtime
  4. Compare baseline startup vs AOT-cached startup

What to Look For

Key Takeaway

Leyden is the successor to AppCDS — it caches method profiles and JIT data in addition to class data. Unlike frameworks with single-property support, Spring Boot requires explicit -XX:AOTMode steps, but the result is the same: dramatically faster startup with no code changes.

Demo 05: REST vs gRPC Performance

Bonus 10 min Spring Boot 4.0.5 spring-grpc

Prerequisites

This demo requires hey (HTTP load tester), grpcurl, and ghz (gRPC load tester). See Prerequisites for installation.

Steps

  1. Navigate: cd demo-05-grpc
  2. Run: ./demo.sh
  3. The script builds and starts the app with REST on :8080 and gRPC on :9000
  4. Runs load tests: hey against REST, ghz against gRPC
  5. Compares throughput, latency, and wire sizes

What to Look For

Demo 06: Low-Latency G1GC vs ZGC

Bonus 10 min Podman Compose Grafana

Steps

  1. Navigate: cd demo-06-latency
  2. Start: ./demo.sh (launches two Spring Boot instances + Prometheus + Grafana)
  3. Open Grafana: http://localhost:3000
  4. Generate allocation pressure on both:
    # G1GC instance
    curl "http://localhost:8080/pressure?mb=50&iterations=10"
    # ZGC instance
    curl "http://localhost:8081/pressure?mb=50&iterations=10"
  5. Compare GC pause histograms in Grafana — side by side
  6. Stop: podman-compose down

What to Look For

Key Takeaway

If your P99 GC pause exceeds 500ms, switch to ZGC. Don't try to tune G1GC parameters — switch the algorithm. The throughput cost (5-15%) is almost always worth the latency consistency.

Demo 07: Right-Sizing & Cost Analysis

Bonus 5 min Python only

Steps

  1. Navigate: cd demo-07-rightsizing
  2. Run: python3 analyze.py (no containers needed)
  3. Review the output: workload analysis, optimization recommendations, and cost savings

What to Look For

Key Takeaway

Right-sizing is the highest ROI optimization. One afternoon of analysis can save $80K+/year per cluster. The script generates ready-to-paste Kubernetes resource specs.

Demo 08: Project Panama FFM — Native C++ Interop

Bonus 5 min JDK 25 3-stage build

Steps

  1. Navigate: cd demo-08-panama
  2. Run: ./demo.sh (3-stage build: UBI9 C++ → Temurin 25 Java → Temurin 25 JRE)
  3. Call the REST endpoints:
    curl http://localhost:8080/panama/stats
    curl http://localhost:8080/panama/system-load
    curl -X POST http://localhost:8080/panama/compute \
      -H "Content-Type: application/json" \
      -d '{"values": [1.0, 2.0, 3.0, 4.0, 5.0]}'

What to Look For

Demo 09: AI Inference — LangChain4j + ONNX

Bonus 5 min JDK 25 LangChain4j

Steps

  1. Navigate: cd demo-09-onnx
  2. Run: ./demo.sh (builds with Temurin 25, bundles MiniLM-L6-v2 model)
  3. Call the REST endpoints:
    # Generate an embedding
    curl -X POST http://localhost:8080/onnx/embed \
      -H "Content-Type: text/plain" \
      -d "JVM garbage collection optimization"
    
    # Compare similarity
    curl -X POST http://localhost:8080/onnx/similarity \
      -H "Content-Type: application/json" \
      -d '{"text1": "JVM tuning", "text2": "Java performance"}'
    
    # Benchmark
    curl http://localhost:8080/onnx/benchmark

What to Look For

Key Takeaway

LangChain4j + ONNX Runtime lets you run AI inference as a single Spring Boot deployment unit with no GPU and no Python dependency. Account for the native memory overhead when sizing containers.

Summary — What You've Learned

DemoTechniqueImpact
01UseContainerSupport + MaxRAMPercentagePrevents OOMKill, correct heap sizing
02Actuator + Micrometer + PrometheusFull JVM observability
03AppCDS 3-stage Containerfile35-55% faster startup
04Project Leyden AOT Cache40-55% faster startup (JDK 25)
05Spring gRPC + Protobuf10x smaller payloads, built-in streaming
06ZGC vs G1GC comparison<1ms pauses vs 50-500ms
07Right-sizing analysis$80K+/year savings, 2-3x pod density
08Panama FFM native interopSafe native calls, no JNI
09ONNX AI inference on JVMNo Python sidecar, CPU-only
Next: Apply to Your App →