28.4 CDS in Production and Performance Optimization

Deploying CDS in production environments requires careful planning, monitoring, and optimization strategies to maximize benefits.

Production Deployment Strategies

// Production CDS Deployment
public class ProductionDeployment {

    public static void printDeploymentStrategies() {
        System.out.println("=== PRODUCTION DEPLOYMENT STRATEGIES ===");

        System.out.println("\n--- CONTAINERIZED DEPLOYMENTS ---");

        System.out.println("\nDocker Strategy 1 - Archive in image:");
        System.out.println("  FROM openjdk:17-slim AS builder");
        System.out.println("  WORKDIR /build");
        System.out.println("  ");
        System.out.println("  # Copy application");
        System.out.println("  COPY app.jar .");
        System.out.println("  COPY lib/ ./lib/");
        System.out.println("  ");
        System.out.println("  # Create CDS archive");
        System.out.println("  RUN java -XX:ArchiveClassesAtExit=app.jsa \\");
        System.out.println("           -jar app.jar --warmup-and-exit");
        System.out.println("  ");
        System.out.println("  # Production stage");
        System.out.println("  FROM openjdk:17-slim");
        System.out.println("  WORKDIR /app");
        System.out.println("  ");
        System.out.println("  # Copy application and archive");
        System.out.println("  COPY --from=builder /build/app.jar .");
        System.out.println("  COPY --from=builder /build/lib/ ./lib/");
        System.out.println("  COPY --from=builder /build/app.jsa .");
        System.out.println("  ");
        System.out.println("  # Run with CDS");
        System.out.println("  CMD [\"java\", \\");
        System.out.println("       \"-XX:SharedArchiveFile=/app/app.jsa\", \\");
        System.out.println("       \"-Xshare:on\", \\");
        System.out.println("       \"-jar\", \"app.jar\"]");

        System.out.println("\nBenefits:");
        System.out.println("  ✓ Archive baked into image");
        System.out.println("  ✓ Consistent across containers");
        System.out.println("  ✓ No runtime generation");
        System.out.println("  ✓ Fastest container startup");

        System.out.println("\n--- KUBERNETES DEPLOYMENT ---");

        System.out.println("\nDeployment YAML:");
        System.out.println("  apiVersion: apps/v1");
        System.out.println("  kind: Deployment");
        System.out.println("  metadata:");
        System.out.println("    name: myapp");
        System.out.println("  spec:");
        System.out.println("    replicas: 10  # Multiple instances benefit most");
        System.out.println("    template:");
        System.out.println("      spec:");
        System.out.println("        containers:");
        System.out.println("        - name: myapp");
        System.out.println("          image: myapp:1.0.0-cds");
        System.out.println("          env:");
        System.out.println("          - name: JAVA_OPTS");
        System.out.println("            value: >");
        System.out.println("              -XX:SharedArchiveFile=/app/app.jsa");
        System.out.println("              -Xshare:on");
        System.out.println("              -Xlog:cds=info");
        System.out.println("          resources:");
        System.out.println("            requests:");
        System.out.println("              memory: \"512Mi\"  # Reduced due to CDS");
        System.out.println("              cpu: \"500m\"");
        System.out.println("          readinessProbe:");
        System.out.println("            httpGet:");
        System.out.println("              path: /health");
        System.out.println("              port: 8080");
        System.out.println("            initialDelaySeconds: 10  # Faster startup");

        System.out.println("\n--- MICROSERVICES ARCHITECTURE ---");

        System.out.println("\nShared base layer strategy:");
        System.out.println("  ");
        System.out.println("  1. Create framework archive (Spring Boot):");
        System.out.println("     framework.jsa");
        System.out.println("     • Spring Framework");
        System.out.println("     • Spring Boot");
        System.out.println("     • Common libraries");
        System.out.println("     • Size: ~60MB");
        System.out.println("  ");
        System.out.println("  2. Share across services:");
        System.out.println("     service-a: framework.jsa + service-a.jsa (5MB)");
        System.out.println("     service-b: framework.jsa + service-b.jsa (4MB)");
        System.out.println("     service-c: framework.jsa + service-c.jsa (6MB)");
        System.out.println("  ");
        System.out.println("  3. Memory savings:");
        System.out.println("     Without CDS: 3 services × 80MB = 240MB");
        System.out.println("     With CDS:    60MB shared + (5+4+6)MB = 75MB");
        System.out.println("     Savings:     165MB (69% reduction)");
    }

    public static void printMonitoring() {
        System.out.println("\n=== PRODUCTION MONITORING ===");

        System.out.println("\n--- STARTUP TIME METRICS ---");

        System.out.println("\nMeasure JVM startup:");
        System.out.println("  # Add to application");
        System.out.println("  public class Application {");
        System.out.println("      private static final long START = ");
        System.out.println("          System.currentTimeMillis();");
        System.out.println("      ");
        System.out.println("      public static void main(String[] args) {");
        System.out.println("          SpringApplication.run(Application.class, args);");
        System.out.println("          long duration = System.currentTimeMillis() - START;");
        System.out.println("          System.out.println(\"Startup: \" + duration + \"ms\");");
        System.out.println("      }");
        System.out.println("  }");

        System.out.println("\nPrometheus metrics:");
        System.out.println("  # Application startup duration");
        System.out.println("  application_startup_seconds{cds=\"enabled\"} 2.5");
        System.out.println("  application_startup_seconds{cds=\"disabled\"} 4.2");

        System.out.println("\n--- MEMORY FOOTPRINT ---");

        System.out.println("\nMonitor resident memory:");
        System.out.println("  # In container");
        System.out.println("  kubectl top pod myapp-xyz");
        System.out.println("  ");
        System.out.println("  NAME          CPU   MEMORY");
        System.out.println("  myapp-xyz     50m   420Mi  # With CDS");
        System.out.println("  myapp-abc     50m   512Mi  # Without CDS");

        System.out.println("\nJMX monitoring:");
        System.out.println("  # Enable JMX");
        System.out.println("  -Dcom.sun.management.jmxremote");
        System.out.println("  -Dcom.sun.management.jmxremote.port=9010");
        System.out.println("  -Dcom.sun.management.jmxremote.authenticate=false");
        System.out.println("  -Dcom.sun.management.jmxremote.ssl=false");
        System.out.println("  ");
        System.out.println("  # Query memory usage");
        System.out.println("  jconsole localhost:9010");

        System.out.println("\n--- CDS VERIFICATION ---");

        System.out.println("\nLog analysis:");
        System.out.println("  # Check if CDS is active");
        System.out.println("  kubectl logs myapp-xyz | grep -i cds");
        System.out.println("  ");
        System.out.println("  Expected:");
        System.out.println("  [info][cds] Opened archive /app/app.jsa");
        System.out.println("  [info][cds] Mapped 2345 classes");

        System.out.println("\nStartup logs:");
        System.out.println("  java -Xlog:cds=info:file=cds.log \\");
        System.out.println("       -XX:SharedArchiveFile=app.jsa \\");
        System.out.println("       -jar app.jar");

        System.out.println("\nParse logs:");
        System.out.println("  grep 'Mapped' cds.log");
        System.out.println("  → Shows number of classes loaded from archive");
    }
}

Performance Benchmarking

// CDS Performance Benchmarking
public class CDSBenchmarking {

    public static void printBenchmarkingGuide() {
        System.out.println("=== CDS PERFORMANCE BENCHMARKING ===");

        System.out.println("\n--- STARTUP TIME BENCHMARK ---");

        System.out.println("\nBenchmark script:");
        System.out.println("  #!/bin/bash");
        System.out.println("  ");
        System.out.println("  # Benchmark without CDS");
        System.out.println("  echo \"Without CDS:\"");
        System.out.println("  for i in {1..20}; do");
        System.out.println("    time java -Xshare:off \\");
        System.out.println("              -jar app.jar --quick-exit");
        System.out.println("  done 2>&1 | grep real | awk '{print $2}'");
        System.out.println("  ");
        System.out.println("  # Benchmark with CDS");
        System.out.println("  echo \"With CDS:\"");
        System.out.println("  for i in {1..20}; do");
        System.out.println("    time java -XX:SharedArchiveFile=app.jsa \\");
        System.out.println("              -Xshare:on \\");
        System.out.println("              -jar app.jar --quick-exit");
        System.out.println("  done 2>&1 | grep real | awk '{print $2}'");

        System.out.println("\nExample results:");
        System.out.println("  Without CDS: Average 3.2s (min 3.0s, max 3.5s)");
        System.out.println("  With CDS:    Average 2.1s (min 2.0s, max 2.3s)");
        System.out.println("  Improvement: 34% faster startup");

        System.out.println("\n--- MEMORY FOOTPRINT BENCHMARK ---");

        System.out.println("\nMultiple instances test:");
        System.out.println("  #!/bin/bash");
        System.out.println("  ");
        System.out.println("  # Start 10 instances");
        System.out.println("  for i in {1..10}; do");
        System.out.println("    java -XX:SharedArchiveFile=app.jsa \\");
        System.out.println("         -Xshare:on \\");
        System.out.println("         -jar app.jar --port=$((8080+i)) &");
        System.out.println("    echo $! >> pids.txt");
        System.out.println("  done");
        System.out.println("  ");
        System.out.println("  # Wait for startup");
        System.out.println("  sleep 30");
        System.out.println("  ");
        System.out.println("  # Measure total memory");
        System.out.println("  ps -o pid,rss -p $(cat pids.txt | paste -sd,)");

        System.out.println("\nExample results:");
        System.out.println("  Without CDS:");
        System.out.println("    Per-instance: 520MB RSS");
        System.out.println("    Total 10 instances: 5,200MB");
        System.out.println("    Shared memory: ~400MB");
        System.out.println("    Physical RAM: ~4,800MB");
        System.out.println("  ");
        System.out.println("  With CDS:");
        System.out.println("    Per-instance: 480MB RSS");
        System.out.println("    Total 10 instances: 4,800MB");
        System.out.println("    Shared memory: ~800MB (CDS archive)");
        System.out.println("    Physical RAM: ~4,000MB");
        System.out.println("  ");
        System.out.println("  Savings: 800MB (17% reduction)");

        System.out.println("\n--- THROUGHPUT IMPACT ---");

        System.out.println("\nLoad test with JMeter:");
        System.out.println("  # Create test plan");
        System.out.println("  Thread Group: 100 threads");
        System.out.println("  Ramp-up: 10s");
        System.out.println("  Duration: 300s");
        System.out.println("  ");
        System.out.println("  # Run against CDS-enabled instance");
        System.out.println("  jmeter -n -t test-plan.jmx \\");
        System.out.println("         -l results-cds.jtl");
        System.out.println("  ");
        System.out.println("  # Run against baseline");
        System.out.println("  jmeter -n -t test-plan.jmx \\");
        System.out.println("         -l results-baseline.jtl");

        System.out.println("\nResults:");
        System.out.println("  Baseline:    1,200 req/s avg, 50ms p95");
        System.out.println("  With CDS:    1,220 req/s avg, 48ms p95");
        System.out.println("  Impact:      Minimal (within margin of error)");
        System.out.println("  ");
        System.out.println("  Note: CDS improves startup, not steady-state throughput");
    }

    public static void printRealWorldCaseStudies() {
        System.out.println("\n=== REAL-WORLD CASE STUDIES ===");

        System.out.println("\n--- CASE 1: MICROSERVICES PLATFORM ---");

        System.out.println("\nScenario:");
        System.out.println("  • 15 Spring Boot microservices");
        System.out.println("  • Kubernetes deployment");
        System.out.println("  • 5 replicas per service (75 pods total)");
        System.out.println("  • Frequent scale-up/down");

        System.out.println("\nBefore CDS:");
        System.out.println("  • Startup time: 45-60s per pod");
        System.out.println("  • Memory per pod: 650MB");
        System.out.println("  • Total cluster memory: 48GB");
        System.out.println("  • Scale-up latency: 60s");

        System.out.println("\nAfter CDS (shared framework layer):");
        System.out.println("  • Startup time: 25-35s per pod");
        System.out.println("  • Memory per pod: 520MB");
        System.out.println("  • Total cluster memory: 39GB");
        System.out.println("  • Scale-up latency: 35s");

        System.out.println("\nBenefits:");
        System.out.println("  ✓ 42% faster startup");
        System.out.println("  ✓ 20% memory reduction");
        System.out.println("  ✓ 9GB cluster memory saved");
        System.out.println("  ✓ Better auto-scaling responsiveness");

        System.out.println("\n--- CASE 2: BATCH PROCESSING ---");

        System.out.println("\nScenario:");
        System.out.println("  • Data processing pipeline");
        System.out.println("  • 1,000 short-lived jobs per day");
        System.out.println("  • Each job runs 30-120s");
        System.out.println("  • Startup overhead significant");

        System.out.println("\nBefore CDS:");
        System.out.println("  • Job startup: 12s");
        System.out.println("  • Avg job duration: 45s total (12s + 33s work)");
        System.out.println("  • Daily startup overhead: 12,000s (3.3 hours)");

        System.out.println("\nAfter CDS:");
        System.out.println("  • Job startup: 4s");
        System.out.println("  • Avg job duration: 37s total (4s + 33s work)");
        System.out.println("  • Daily startup overhead: 4,000s (1.1 hours)");

        System.out.println("\nBenefits:");
        System.out.println("  ✓ 67% faster startup");
        System.out.println("  ✓ 18% total time reduction");
        System.out.println("  ✓ 2.2 hours saved daily");
        System.out.println("  ✓ Better resource utilization");

        System.out.println("\n--- CASE 3: SERVERLESS FUNCTIONS ---");

        System.out.println("\nScenario:");
        System.out.println("  • AWS Lambda functions");
        System.out.println("  • Cold start problem");
        System.out.println("  • Java 17 runtime");
        System.out.println("  • 1GB memory allocation");

        System.out.println("\nBefore CDS:");
        System.out.println("  • Cold start: 8-12s");
        System.out.println("  • Warm invocation: 150ms");
        System.out.println("  • Timeout issues on cold start");

        System.out.println("\nAfter CDS (with custom runtime):");
        System.out.println("  • Cold start: 3-5s");
        System.out.println("  • Warm invocation: 150ms (unchanged)");
        System.out.println("  • Fewer timeouts");

        System.out.println("\nAlternative - GraalVM Native Image:");
        System.out.println("  • Cold start: 0.5-1s");
        System.out.println("  • Warm invocation: 120ms");
        System.out.println("  • Better for serverless");
    }
}

Optimization Techniques

// CDS Optimization Techniques
public class CDSOptimization {

    public static void printOptimizationTechniques() {
        System.out.println("=== CDS OPTIMIZATION TECHNIQUES ===");

        System.out.println("\n--- ARCHIVE SIZE OPTIMIZATION ---");

        System.out.println("\n1. Include only hot classes:");
        System.out.println("   # Analyze class load frequency");
        System.out.println("   java -Xlog:cds+load=debug \\");
        System.out.println("        -jar app.jar > classes-loaded.log");
        System.out.println("   ");
        System.out.println("   # Count class loads");
        System.out.println("   awk '{print $NF}' classes-loaded.log | \\");
        System.out.println("       sort | uniq -c | sort -rn > frequency.txt");
        System.out.println("   ");
        System.out.println("   # Keep top 80% (Pareto principle)");
        System.out.println("   head -n 1000 frequency.txt | \\");
        System.out.println("       awk '{print $2}' > hot-classes.lst");

        System.out.println("\n2. Exclude rarely-used classes:");
        System.out.println("   # Remove test frameworks");
        System.out.println("   grep -v 'org/junit' classes.lst > filtered.lst");
        System.out.println("   grep -v 'org/testng' filtered.lst > final.lst");
        System.out.println("   ");
        System.out.println("   # Remove internal classes");
        System.out.println("   grep -v 'sun/reflect' final.lst > optimized.lst");

        System.out.println("\n--- LAYERING STRATEGY ---");

        System.out.println("\nOptimal layering:");
        System.out.println("  Layer 1 (default): JDK classes");
        System.out.println("    Size: ~20MB");
        System.out.println("    Updates: Never (tied to JDK)");
        System.out.println("  ");
        System.out.println("  Layer 2 (framework): Spring, Hibernate, etc.");
        System.out.println("    Size: ~40MB");
        System.out.println("    Updates: Quarterly (framework upgrades)");
        System.out.println("  ");
        System.out.println("  Layer 3 (app): Application classes");
        System.out.println("    Size: ~8MB");
        System.out.println("    Updates: Daily (code changes)");

        System.out.println("\nBenefits:");
        System.out.println("  ✓ Small top layer → fast regeneration");
        System.out.println("  ✓ Share stable layers across services");
        System.out.println("  ✓ Reduce archive generation time");

        System.out.println("\n--- WARMUP OPTIMIZATION ---");

        System.out.println("\nComprehensive warmup:");
        System.out.println("  @Component");
        System.out.println("  public class WarmupService {");
        System.out.println("      @EventListener(ApplicationReadyEvent.class)");
        System.out.println("      public void warmup() {");
        System.out.println("          // Exercise all endpoints");
        System.out.println("          restTemplate.getForEntity(\"/api/users\", ...);");
        System.out.println("          restTemplate.postForEntity(\"/api/orders\", ...);");
        System.out.println("          ");
        System.out.println("          // Trigger lazy initialization");
        System.out.println("          hibernate.getSessionFactory();");
        System.out.println("          ");
        System.out.println("          // Load configurations");
        System.out.println("          config.getAllProperties();");
        System.out.println("      }");
        System.out.println("  }");

        System.out.println("\n--- COMBINED OPTIMIZATIONS ---");

        System.out.println("\nCDS + JVM tuning:");
        System.out.println("  java -XX:SharedArchiveFile=app.jsa \\");
        System.out.println("       -Xshare:on \\");
        System.out.println("       -XX:+TieredCompilation \\");
        System.out.println("       -XX:TieredStopAtLevel=1 \\  # Skip C2 for startup");
        System.out.println("       -Xverify:none \\             # Skip verification");
        System.out.println("       -XX:+UseStringDeduplication \\");
        System.out.println("       -jar app.jar");

        System.out.println("\nStartup optimization stack:");
        System.out.println("  • CDS for class loading:       -30%");
        System.out.println("  • Skip verification:           -10%");
        System.out.println("  • C1-only compilation:         -15%");
        System.out.println("  • Lazy initialization:         -20%");
        System.out.println("  Combined:                      -75% startup time");
    }

    public static void printContinuousOptimization() {
        System.out.println("\n=== CONTINUOUS OPTIMIZATION ===");

        System.out.println("\n--- MONITORING LOOP ---");

        System.out.println("\n1. Measure baseline:");
        System.out.println("   • Current startup time");
        System.out.println("   • Current memory usage");
        System.out.println("   • Archive size");

        System.out.println("\n2. Profile class loading:");
        System.out.println("   • Which classes are loaded?");
        System.out.println("   • When are they loaded?");
        System.out.println("   • How frequently?");

        System.out.println("\n3. Optimize archive:");
        System.out.println("   • Update class list");
        System.out.println("   • Regenerate archive");
        System.out.println("   • Test changes");

        System.out.println("\n4. Deploy and verify:");
        System.out.println("   • Gradual rollout");
        System.out.println("   • Monitor metrics");
        System.out.println("   • Compare to baseline");

        System.out.println("\n5. Iterate:");
        System.out.println("   • Quarterly review");
        System.out.println("   • After major updates");
        System.out.println("   • When performance degrades");
    }
}

Troubleshooting Production Issues

// Production Troubleshooting
public class ProductionTroubleshooting {

    public static void printTroubleshooting() {
        System.out.println("=== PRODUCTION TROUBLESHOOTING ===");

        System.out.println("\n--- ISSUE 1: NO PERFORMANCE IMPROVEMENT ---");

        System.out.println("\nSymptoms:");
        System.out.println("  • CDS enabled but same startup time");
        System.out.println("  • Expected improvement not realized");

        System.out.println("\nDiagnosis:");
        System.out.println("  # Check if archive is used");
        System.out.println("  kubectl logs pod-xyz | grep -i cds");
        System.out.println("  ");
        System.out.println("  # Check archive coverage");
        System.out.println("  java -Xlog:cds=info -jar app.jar");

        System.out.println("\nCommon causes:");
        System.out.println("  • Archive not loaded (classpath mismatch)");
        System.out.println("  • Insufficient classes in archive");
        System.out.println("  • Bottleneck elsewhere (I/O, initialization)");
        System.out.println("  • Single instance (no memory benefit)");

        System.out.println("\n--- ISSUE 2: ARCHIVE MISMATCH ---");

        System.out.println("\nSymptoms:");
        System.out.println("  • 'Unable to use shared archive' warning");
        System.out.println("  • Application runs but CDS disabled");

        System.out.println("\nDiagnosis:");
        System.out.println("  java -Xshare:on \\  # Force failure");
        System.out.println("       -Xlog:cds=debug \\");
        System.out.println("       -XX:SharedArchiveFile=app.jsa \\");
        System.out.println("       -jar app.jar");

        System.out.println("\nSolutions:");
        System.out.println("  • Regenerate archive for current JDK");
        System.out.println("  • Match compressed oops setting");
        System.out.println("  • Verify classpath matches");
        System.out.println("  • Check JVM flags match dump");

        System.out.println("\n--- ISSUE 3: MEMORY NOT SHARED ---");

        System.out.println("\nSymptoms:");
        System.out.println("  • Multiple instances use same memory");
        System.out.println("  • Expected memory savings not realized");

        System.out.println("\nDiagnosis:");
        System.out.println("  # Check shared memory on Linux");
        System.out.println("  pmap -x $(pidof java) | grep app.jsa");
        System.out.println("  ");
        System.out.println("  # Look for shared vs private pages");
        System.out.println("  cat /proc/$(pidof java)/smaps | \\");
        System.out.println("      grep -A 15 app.jsa");

        System.out.println("\nCommon causes:");
        System.out.println("  • Copy-on-write triggered (pages modified)");
        System.out.println("  • Different container namespaces");
        System.out.println("  • Archive copied per container");
        System.out.println("  • Host FS not shared");

        System.out.println("\n--- ISSUE 4: SLOW ARCHIVE CREATION ---");

        System.out.println("\nSymptoms:");
        System.out.println("  • Archive dump takes >5 minutes");
        System.out.println("  • CI/CD pipeline slowed");

        System.out.println("\nSolutions:");
        System.out.println("  • Reduce class list size");
        System.out.println("  • Use layered archives (regenerate top only)");
        System.out.println("  • Cache framework layer");
        System.out.println("  • Parallelize multi-service builds");
    }
}

Best Practices Checklist

// Production Best Practices
public class ProductionBestPractices {

    public static void printChecklist() {
        System.out.println("=== PRODUCTION BEST PRACTICES ===");

        System.out.println("\n--- DEPLOYMENT ---");
        System.out.println("☐ Archive baked into container image");
        System.out.println("☐ Archive versioned with application");
        System.out.println("☐ Automated regeneration in CI/CD");
        System.out.println("☐ Separate archives per environment (dev/prod)");
        System.out.println("☐ Layered archives for microservices");

        System.out.println("\n--- VERIFICATION ---");
        System.out.println("☐ Test with -Xshare:on in staging");
        System.out.println("☐ Verify startup time improvement");
        System.out.println("☐ Confirm memory savings (multiple instances)");
        System.out.println("☐ Check logs for CDS activation");
        System.out.println("☐ Benchmark before/after");

        System.out.println("\n--- MONITORING ---");
        System.out.println("☐ Track startup time metrics");
        System.out.println("☐ Monitor memory footprint");
        System.out.println("☐ Alert on CDS failures");
        System.out.println("☐ Log archive usage");
        System.out.println("☐ Regular performance reviews");

        System.out.println("\n--- MAINTENANCE ---");
        System.out.println("☐ Regenerate on JDK updates");
        System.out.println("☐ Regenerate on dependency changes");
        System.out.println("☐ Document archive creation process");
        System.out.println("☐ Keep class lists in version control");
        System.out.println("☐ Archive rotation strategy");

        System.out.println("\n--- OPTIMIZATION ---");
        System.out.println("☐ Profile class loading patterns");
        System.out.println("☐ Include only frequently-used classes");
        System.out.println("☐ Use layered archives for reusability");
        System.out.println("☐ Combine with other optimizations");
        System.out.println("☐ Continuous benchmarking");
    }
}

Best Practices

  • Bake archives into images: Pre-generate during container build.
  • Monitor startup time: Track metrics to validate improvements.
  • Use layered archives: Share framework layer across microservices.
  • Automate regeneration: Include in CI/CD pipeline.
  • Test thoroughly: Verify with -Xshare:on before production.
  • Benchmark regularly: Ensure continued benefits as code evolves.
  • Plan for multiple instances: CDS memory benefits require >1 JVM.
  • Version archives properly: Tie to application and JDK version.
  • Document processes: Ensure team understands CDS setup.
  • Combine optimizations: CDS + lazy init + C1-only for maximum startup speed.