Explore by category
JVM CLI
Every JDK ships with a set of diagnostic and management command-line tools that live inside the bin/ directory. Because they travel with the runtime, they are the first tools you should reach for when a Java process misbehaves: they cost nothing, require no agent or instrumentation, and work almost everywhere.
Profiling
When a Java service is slow, a profiler tells you where the CPU time and allocations actually go instead of wherever a hunch points. Modern JVM profiling has largely converged on two complementary techniques: sampled async profiling (async-profiler) and events recorded by the JVM itself (Java Flight Recorder).
Memory
OutOfMemoryError reports, growing heap graphs in your monitoring, and slowly-rotting response times are usually signs one of two things: a leak, or excessive garbage-collection pressure. The tools in this category are how you turn those symptoms into an exact cause.
Bytecode
The Java bytecode format (class files) is a stable, documented target. Because the JVM executes bytecode rather than source, any JVM language can compile to it, and runtime libraries can generate or transform classes after compilation. This is what powers proxies, ORMs, mocking frameworks and most modern frameworks' cleverness.
Build
A modern JVM project is built by one of a small set of tools: Maven and Gradle dominate, with sbt and Bazel in specific niches. All of them orchestrate compilation, testing, packaging and dependency resolution against repositories such as Maven Central.
Testing
Test-driven code on the JVM rests on a durable core of tooling: a test framework (JUnit 5 or TestNG), an assertion library (AssertJ), and a mocking library (Mockito). Around that core, Testcontainers lets you spin up real infrastructure for integration tests, and JMH is the only sane way to microbenchmark code on a modern JIT-compiled JVM.
Kubernetes
Running Java in Kubernetes changes how you think about JVM settings. The JVM no longer sees a fixed machine — it sees the CPU and memory limits you place on the pod, and it must cope with cgroup capping, container sharding and the container's ephemeral nature. Get the memory settings wrong and you get either OOMKilled pods or heap starvation.