skip to content

What does -XX:+AutoCreateSharedArchive do, and how does it change the CDS workflow versus the manual two-step approach?

level: seniorimportance: nice to knowfreq 12%

answer

  1. JDK 19+ one-flag create-and-use
  2. Missing/stale -> regenerate at exit; valid -> map+use
  3. Self-heals on JDK/classpath change (no hard fail)
  4. First run always cold + pays dump cost
  5. Prod prefers deterministic onRefresh training run baked in image

basics

~20 s

-XX:+AutoCreateSharedArchive (JDK 19+), used with -XX:SharedArchiveFile=app.jsa, makes one flag do both jobs: if the archive is missing or stale it creates it at exit, and if it's valid it uses it. No separate training-run flag needed.

solid answer

~50 s

`-XX:+AutoCreateSharedArchive` (introduced in **JDK 19**) collapses the two-phase dynamic-CDS workflow into a single always-on flag, used together with `-XX:SharedArchiveFile=<path>`. On the first run the archive doesn't exist, so the JVM runs normally and dumps it at exit; on subsequent runs the archive exists and is memory-mapped for faster startup. If the archive is **incompatible** — different JDK version or a changed classpath — the JVM detects that, ignores the stale archive, runs normally, and regenerates it, so it self-heals instead of failing. This is great for **developer/local convenience**: you don't script a separate `-XX:ArchiveClassesAtExit` training run. The tradeoff is that the *very first* run (and any run after an invalidating change) is a normal-speed run that also pays the dump cost, and the archive reflects whatever that run happened to load. For production, an explicit, controlled training run (e.g., Spring Boot's `onRefresh`) baked into the image build is usually preferred because it's deterministic.

code

java · 11 lines
java
// One stable command, safe to repeat (JDK 19+):
//   java -XX:+AutoCreateSharedArchive \
//        -XX:SharedArchiveFile=application.jsa \
//        -jar app.jar
//
// Run 1: application.jsa absent -> runs normally, dumps archive at exit (COLD)
// Run 2: archive present + compatible -> memory-mapped, fast start (WARM)
// After bumping the JDK or a dependency:
//   archive detected incompatible -> discarded, runs normally, regenerated
//   (self-heals; the manual -XX:ArchiveClassesAtExit approach would need a
//    fresh explicit training run instead)

go deeper

for a junior

Know it's a convenience flag that makes and reuses the archive automatically.

for a middle

Explain the missing/valid/stale branches and that it needs JDK 19+.

for a senior

Weighs auto-create (dev convenience, self-healing) against a deterministic prod training run baked into the image.

for a principal

Sets policy: auto-create for local/dev, pre-built archive in image for prod; understands cold-first-run and coverage-quality implications.

## The manual baseline Classic dynamic CDS is two distinct commands: produce with `-XX:ArchiveClassesAtExit=app.jsa`, then consume with `-XX:SharedArchiveFile=app.jsa`. You script both, and you must re-run the producer whenever things change. ## What `-XX:+AutoCreateSharedArchive` adds (JDK 19+) Used **together with** `-XX:SharedArchiveFile=<path>`, this flag makes a single invocation handle both create-and-use: - **Archive absent** -> the JVM runs normally, records loaded classes, and **dumps the archive at exit**. That first run is not accelerated. - **Archive present and compatible** -> the JVM **memory-maps and uses** it — accelerated startup. - **Archive present but incompatible** (JDK version changed, or classpath changed) -> the JVM **detects the mismatch, discards the stale archive, runs normally, and regenerates** it. It self-heals rather than erroring. So one stable command line — `java -XX:+AutoCreateSharedArchive -XX:SharedArchiveFile=app.jsa -jar app.jar` — is safe to run repeatedly: cold the first time, warm thereafter, auto-refreshed after any change. ## Why it exists / when to use it It targets **iterative/local development** and simple deployments where you don't want to maintain a separate training step. It removes the foot-gun where a stale hand-built archive (wrong JDK) would otherwise be rejected — here it just rebuilds. ## Why production often still uses the explicit training run - **Determinism**: an ad-hoc first run archives whatever classes that particular run touched; a controlled training run (Spring Boot `-Dspring.context.exit=onRefresh`) archives the intended startup path every time. - **No cold first request in prod**: with Auto-create, the first container to start after a change pays the full slow-start + dump cost. Baking a pre-built archive into the image at build time means *every* container starts warm. - **Reproducibility in CI**: image builds want the archive produced once, deterministically, and shipped. ## Version note `-XX:+AutoCreateSharedArchive` requires **JDK 19 or later**. On older JDKs you must use the explicit `-XX:ArchiveClassesAtExit` / `-XX:SharedArchiveFile` split. ## Gotchas - It still obeys the **same compatibility rules** — a classpath or JDK change invalidates the archive; the difference is it regenerates rather than fails. - The **first run is never fast**, and it additionally pays the dump cost — don't benchmark CDS on a cold run. - The archive quality depends on what the auto-create run loaded; if that run didn't exercise startup fully, coverage is weaker than a purpose-built training run. - Combine with `-Xlog:cds` to confirm whether a given start mapped or regenerated the archive.

  • Why might you still prefer the explicit training run in production despite AutoCreateSharedArchive being simpler?
    Determinism and no cold-start penalty in prod. Auto-create archives whatever the first run loaded and forces that first (or post-change) container to start slow and pay the dump cost. A controlled onRefresh training run at image-build time archives the intended startup path and ships a warm archive so every container starts fast.
  • What happens with AutoCreateSharedArchive after you upgrade the JDK?
    The existing archive is detected as incompatible with the new JDK, discarded, and regenerated on that run (which is therefore cold). It self-heals rather than failing to start.

saying these in an interview costs you the question

  • Thinking the first auto-create run is already fast
  • Believing auto-create removes the JDK/classpath matching requirement (it regenerates, it doesn't ignore the rule)
  • Using it on a pre-JDK-19 runtime
  • Assuming auto-create's ad-hoc archive is as good as a deterministic onRefresh training run for production

context