CratonVM
CratonVM
A Java Virtual Machine written in Rust, with a custom x86-64 JIT and an opt-in automatic GPU fast path for a documented subset of Java kernels.
CratonVM boots against a real JDK when one is present (JAVA_HOME,
CRATONVM_JAVA_HOME, or java on PATH) and runs fully standalone when it
isn't — its own Rust implementations of the Java standard library mean no JDK
install, no rt.jar, one self-contained binary.
Highlights
- Custom x86-64 JIT — tiered compilation (interpreter → C1 → C2), OSR, LICM, bounds-check elimination, AVX2 SIMD, precise stack maps. Experimental AArch64 backend.
- Automatic GPU fast path — supported pure static array kernels can run on NVIDIA GPUs without API changes. Eligibility is intentionally narrow and unsupported shapes fall back to CPU (see below).
- ZGC by default. The default collector is a memory-backed, stop-the-world ZGC
(
-XX:+UseZGC). It has thread-local allocation buffers that the JIT allocates from inline, and parallel sliding compaction (kill switchCRATONVM_ZGC_RELOCATE=0).- Parallel marking (
CRATONVM_ZGC_PARMARK=<workers>), concurrent marking (CRATONVM_ZGC_CONC_START) and a generational mode (CRATONVM_ZGC_GENERATIONAL=1) are opt-in. - The colored-pointer load barrier is built but not yet armed.
-XX:+UseGenerationalGCselects the young/old collector with a Cheney moving young generation; a cycle that cannot prove complete root coverage falls back to a non-moving sweep.- Region-based G1 is experimental and opt-in (
-XX:+UseG1GC). - See ARCHITECTURE.md.
- Parallel marking (
- Real frameworks run — Spring, Spring Boot, Tomcat, Netty, Hibernate, Hibernate Reactive, H2 Database, Postgres driver boot and pass large test suites.
- Rust implementation — Rust removes many ambient memory hazards, but the
VM, JIT, GC, FFI, I/O, AWT, CUDA, and JFR contain reviewed and still-being-
audited
unsaferegions. See SECURITY.md. - JNI & embedding — JNI Invocation API, a stable C-ABI library
(
libcratonvm), and a Rust facade (cratonvm-embed). - Observability & hardening — Java Flight Recorder, bytecode verification, opt-in I/O confinement and network egress policy (docs/SECURITY_HARDENING.md).
Performance
CPU, vs HotSpot JDK 25 C2 — same flags both sides, checksum-verified against HotSpot on every run (zero mismatches):
| Benchmark | JDK 25 C2 | CratonVM | Ratio | Growth |
|---|---|---|---|---|
| Arithmetic (2B ops)‡ | 1,877 ms | 2,047 ms | 1.09x | linear |
| Fibonacci(44)‡ | 1,530 ms | 3,699 ms | 2.42x | linear |
| Sieve (100K × 20K)‡ | 2,369 ms | 1,748 ms | 0.74x | parity |
| Matrix 1280×1280‡ | 2,344 ms | 2,166 ms | 0.92x | parity |
| Binary Trees (depth 20)‡ | 866 ms | 3,028 ms | 3.50x | super-linear |
| HashMap (100M put/get) | 6,542 ms | 15,565 ms | 2.38x | non-monotonic |
| String/Regex (10M) | 617 ms | 15,120 ms | 24.51x | super-linear |
‡ Measured under G1 (-XX:+UseG1GC); HashMap and String/Regex measured under default ZGC (-XX:+UseZGC) (best-performing collector shown per workload).
All rows run in default strict mode (--jdk-only), isolated fresh process per measurement; see BENCHMARK.md for full multi-configuration data across both collectors and all sizes.
Full per-size data, checksums, CV, and the ZGC-vs-G1 delta are in BENCHMARK.md.
GPU offload, vs HotSpot C2 and TornadoVM 4.0.1 (RTX 2060, N = 2²⁴, warm, full H2D+kernel+D2H round-trip, checksums bit-identical to HotSpot):
| Kernel | HotSpot C2 | TornadoVM GPU | CratonVM GPU | vs HotSpot | vs TornadoVM |
|---|---|---|---|---|---|
| Integer div-chain (48 divs/elem) | 2,179 ms | 27 ms | 7 ms | 311x | 3.9x |
| Double div-chain (64 divs/elem) | 1,784 ms | 135 ms | 82 ms | 21.8x | 1.6x |
| 128 multiply-adds/elem (data-dependent multiplier) | 1,298 ms | 26 ms | 7 ms | 185x | 3.7x |
| Dot-product reduction (int·int → long, x300/elem) | 1,168 ms | unimplemented | 2 ms | 584x | n/a |
| Ray tracer kernel, 7680×4320 (33.2M px) | 837.1 ms | 24.29 ms | 12.29 ms | 68x | 2.0x |
Unlike TornadoVM, the supported automatic path needs no @Parallel
annotations or TaskGraph API — within a deliberately narrow eligibility
subset, not a general promise that arbitrary Java runs on the GPU. Full
results, extra sizes, and methodology:
BENCHMARK.md and docs/gpu/README.md.
What to build on
Boots, runs, and passes large real-world test suites:
- Spring 7.1 / Spring Boot 4.2
- Tomcat 12.0 / Netty 4.2
- Hibernate ORM 7.4 / Hibernate Reactive 4.5
- H2 DB 2.4 / PostgreSQL driver 42.7
- Apache Commons Math 4.0
- Bouncy Castle Java 1.86
Just because it boots and runs large real-world test suites does not mean it is production-ready. But you can start building on it focusing on its main strength - the gpu performance.
Java Version Support
| Version | Key features |
|---|---|
| Java 8 | Full language support, lambdas, streams |
| Java 11 | Nest-based access control |
| Java 17 | Records, sealed classes |
| Java 21 | Pattern matching for switch, virtual threads, sequenced collections |
| Java 25 | Stream gatherers, scoped values, structured concurrency |
Quick Start
Build (Rust 1.88+):
cargo build --release -p cratonvm-cli
Compile and run a class:
javac HelloWorld.java
./target/release/cratonvm -cp . HelloWorld
Run a JAR:
./target/release/cratonvm --jar app.jar
Bigger heap, G1 collector, program arguments:
./target/release/cratonvm -Xmx4g -XX:+UseG1GC -cp "classes:lib/util.jar" com.example.Main arg1 arg2
Command-Line Reference
cratonvm [OPTIONS] <CLASS_NAME> [ARGS]...
cratonvm [OPTIONS] --jar <FILE.jar> [ARGS]...
| Option | Description |
|---|---|
-c, -cp, --classpath <PATH> | Directories and JARs to search. Separator: : (Unix) / ; (Windows). |
--jar <FILE> | Execute a JAR (main class from META-INF/MANIFEST.MF; classpath from the JAR and its manifest Class-Path). |
-Xmx<SIZE>, --Xmx <SIZE> | Maximum heap size (256m, 1g, 8g). Default: 1/4 of physical RAM, or of the container memory limit, clamped to 256 MB..4 GB. The cap is CRATONVM_DEFAULT_HEAP_MAX_MB; CRATONVM_DEFAULT_HEAP_ERGONOMICS=0 restores a fixed 256 MB. |
-XX:+UseG1GC | Use the region-based G1 collector (experimental; ZGC is the default). |
-XX:+UseGenerationalGC | Use the generational (young/old, Cheney young gen) collector instead of ZGC. |
-D<name>=<value> | Set a Java system property. |
--verbose:class | Class-loading trace to stderr. |
--verbose:gc | GC activity to stderr. |
--nojit | Interpreter only (diagnosis / safety fallback). |
--noverify, --Xverify <MODE> | Bytecode verification policy (none / remote / all). |
--java-home <PATH> | Boot from a specific JDK's java.base. |
--synthetic-jdk | Force the built-in Rust standard library even when a JDK is detected. Implies --compatible. |
--jdk-only | Strict mode: real JDK class bytes are authoritative. This is the default; the flag states it explicitly. Conflicts with --compatible and --synthetic-jdk. |
--compatible | Opt out of strict mode: real JDK class library with the pre-2026-09-20 compatibility substitutions. Use it when a program fails only under the default. |
--real-jdk | Deprecated alias for --compatible. |
--Xbootclasspath <PATH> | Override the bootstrap classpath (advanced). |
-V, --version / --help | Version / full option list. |
Every command above is verified against the current binary. --gpu and the
other GPU options require a --features gpu-driver build — see
docs/gpu/README.md.
JDK-only mode — the default since 2026-09-20
The VM treats real JDK class bytes as authoritative: it will not fabricate a
class that has no real bytes, and it will not register or invoke a
synthetic-stub native. Enforcement is at wave 1 (class fabrication and stub
registration enforce; the rest is recorded and counted), so a program that
depends on a substitution may fail here and pass under --compatible. That
difference is the measurement, not a bug in either mode.
A/B a program to see what it depends on:
./target/release/cratonvm -cp . MyApp # default: jdk-only
./target/release/cratonvm --compatible -cp . MyApp # pre-2026-09-20 behaviour
./target/release/cratonvm --jdk-only-report report.json -cp . MyApp
The report works in either mode: under --compatible it is a census of what
strict mode would reject.
Details: docs/jdk-only-migration.md (operator guide); the rest of the JDK-only docset is indexed from docs/README.md.
Limitations
- AWT/Swing are headless (no on-screen rendering); JavaFX is out of tree.
- Reflection and JNI cover the common paths; some edge cases (C-varargs JNI forms, full foreign-thread attach) are partial.
- Cryptography is best-effort and not constant-time everywhere — see docs/CRYPTO_STATUS.md.
Documentation
- Complete manual — installation, use, compatibility, security, performance, operations, embedding, architecture, contributing, and reference
- Documentation index — map of maintained standalone and manual references
- ARCHITECTURE.md — crate layout and subsystem design
- BENCHMARK.md — benchmark methodology and full results
- Performance tuning — measurement-first tuning workflow
- Deployment and operations — packaging, sizing, security boundaries, rollout, and rollback
- Incident response — crash/hang/OOM/wrong-result diagnostic runbook
- Runtime lifecycle and runtime contracts
- docs/GC.md — collectors, barriers, heap layout
- docs/JIT_OPTIMIZATION.md — the JIT optimization journey
- docs/gpu/README.md — GPU offload reference
- docs/EMBEDDING.md — embedding CratonVM in your application
- docs/SECURITY_HARDENING.md — sandboxing and hardening
- docs/CONFIG.md — configuration reference
- docs/jdk-only-migration.md —
--jdk-onlyoperator guide; the rest of the JDK-only docset is indexed from docs/README.md
Building & Testing
cargo build --release # full workspace
cargo test --workspace # unit + integration tests
bash regression-suite/run.sh # fast HotSpot-differential regression suite
Contributing
See CONTRIBUTING.md. Architectural orientation lives in ARCHITECTURE.md; required merge signals are defined by release readiness and the CI workflows.
License
Apache-2.0 — see LICENSE. CratonVM is an independent implementation and is not derived from OpenJDK sources; see THIRD-PARTY-NOTICES.md and TRADEMARKS.md.