HotSpot Is Not “Java”
The assumption some developers make
HotSpot Is Not “Java”

The assumption some developers make
When people say “Java is slow to start” or “Java uses a lot of memory,” they are almost always describing how HotSpot JVM behaves under their workload.
That assumption is so widespread that “Java” and HotSpot have effectively become synonyms in everyday conversation. It’s convenient, but it hides an important truth.
Java is not an implementation. It is a specification.
Java vs JVM: a small distinction with big consequences
Java defines how things should work: the language, the bytecode, and the expected runtime behavior. The JVM is just one way of implementing that contract. OpenJDK happens to ship with HotSpot, which is why most developers never look beyond it.
A good way to think about it is SQL. SQL defines what a query means, but PostgreSQL, MySQL, and Oracle all execute that query differently. You don’t expect identical performance characteristics across them, even if the query is the same.
The JVM ecosystem works the same way. Your Java code is compiled once, but how it behaves at runtime depends heavily on which JVM is executing it.
Other JVMs exist — and they are not niche
HotSpot dominates by default, not because it is universally better, but because it is the one most distributions ship with. Alternatives like Eclipse OpenJ9 and GraalVM are mature, production-grade runtimes with very different design goals.
OpenJ9 comes from a lineage that prioritizes efficiency, particularly in constrained environments. GraalVM, on the other hand, pushes the boundaries of what a JVM can be, including the ability to compile Java applications into native binaries.
These are not experimental tools. They are different interpretations of the same specification.
Same code, different behavior
Consider a typical Spring Boot service. You run it on HotSpot and get the familiar behavior: startup takes a couple of seconds, memory usage stabilizes at a few hundred megabytes, and performance improves as the JIT compiler optimizes frequently executed paths.
Now take that exact same application and run it on OpenJ9. The first thing you may notice is that memory usage drops. Startup can also be faster. This is not because your code changed, but because OpenJ9 makes different trade-offs internally, especially around memory management and class sharing.
Run the same service on GraalVM in native image mode and the experience changes even more. Startup becomes almost instantaneous, and the memory footprint shrinks significantly. It feels less like a traditional Java service and more like a compiled binary from a language like Go. The trade-off is that you lose some of the adaptive optimizations that come from long-running JIT compilation.
At this point, it becomes clear that what we often call “Java performance” is really “HotSpot performance under specific conditions.”
What is actually different under the hood
These differences are not superficial. Each JVM makes deep architectural decisions that shape how applications behave over time.
Compilation strategy is one of the biggest factors. HotSpot relies on tiered JIT compilation, gradually optimizing code as it identifies hot paths. GraalVM introduces a different compiler and can shift work to build time through ahead-of-time compilation. OpenJ9 takes a more conservative and memory-aware approach, often favoring predictable resource usage over aggressive optimization.
Memory management also varies significantly. Garbage collection strategies, object layout, and allocation behavior are implemented differently, which is why the same application can have noticeably different footprints depending on the JVM.
Startup behavior is another area where philosophies diverge. Some JVMs invest heavily in runtime optimization, accepting slower startup in exchange for better long-term performance. Others prioritize fast initialization, which is critical in containerized or serverless environments where instances are frequently created and destroyed.
These are not tuning flags you can easily align across JVMs. They are built-in design decisions.
JVM Implementations Comparison Table

Comparison between main JVM implementations
Choosing a JVM is choosing a behavior
Once you see these differences in practice, it becomes difficult to think of the JVM as an invisible layer.
If you are running a long-lived service where throughput is critical, HotSpot’s mature optimization model is often a strong fit. If you are deploying many instances in a memory-constrained Kubernetes cluster, OpenJ9 can reduce resource pressure in a meaningful way. If your priority is startup time — especially in serverless environments — GraalVM’s native image approach can change the shape of your architecture entirely.
The key point is that these are not edge optimizations. They can materially affect cost, scalability, and user experience.
A subtle but important mindset shift
Most teams spend a lot of time optimizing code and infrastructure, but rarely question the runtime itself. The JVM is usually treated as a constant.
In reality, it is one of the most impactful variables in your system.
Switching JVMs will not fix bad architecture, but it can unlock improvements that are otherwise very difficult to achieve. Lower memory usage, faster startup, and different latency characteristics are all possible without changing your application code.
Final thought
HotSpot is the most common JVM, but it is just one implementation of the Java specification.
Once you separate “Java” from “HotSpot,” you start to see the JVM as a deliberate choice rather than a default. That shift opens up a layer of optimization that many teams never explore, even though it sits right beneath their applications.
Sources
메타데이터
- post_id
- 024da1e9ffca
- slug
- hotspot-is-not-java-024da1e9ffca
- url
- https://medium.com/@rogeriorobetti/hotspot-is-not-java-024da1e9ffca
- canonical_url
- https://medium.com/@rogeriorobetti/hotspot-is-not-java-024da1e9ffca
- author_url
- https://medium.com/@rogeriorobetti
- status
- ok
- fetched_at
- 2026-06-24 13:29:15