← ClaudeAtlas

mir-backend-jvmlisted

Make It Right (JVM runtime tier). Java 21+ / Kotlin runtime reliability footguns shared across EVERY JVM backend framework (Spring Boot, Quarkus, Micronaut, Vert.x) — distinct from the generic backend gates and from any one framework's mechanics. Covers: thread-pool sizing and pool-exhaustion deadlock, blocking I/O on platform threads, Java 21 virtual threads and carrier-thread pinning inside synchronized/native calls, GC pause tuning (G1 vs ZGC/Shenandoah), container-aware heap sizing (-XX:MaxRAMPercentage vs hard -Xmx), cold-start / JIT warmup cost and mitigations (GraalVM native image, CRaC, AOT), shared-mutable-state visibility (happens-before, volatile, final, data races), and ThreadLocal leaks in pooled threads. TRIGGER when the backend runtime is Java or Kotlin — sits between mir-backend (generic gates) and the framework module (e.g. mir-backend-jvm-spring). SKIP for Python, Node, Go, Rust, .NET, Ruby, PHP, BEAM runtimes (each has its own mir-backend-<runtime> tier), and for framework-library mechanics
anantbhandarkar/make-it-right · ★ 12 · API & Backend · score 83
Install: claude install-skill anantbhandarkar/make-it-right
# /mir-backend-jvm · Make It Right (JVM runtime) The middle tier. `mir-backend` decides **what is correct** (any language). The framework module (e.g. `mir-backend-jvm-spring`) knows the **library's mechanics**. This tier owns what's true for **all JVM backends because they run on the HotSpot JVM** — the threading model, garbage collector, memory model, and process lifecycle that Spring Boot, Quarkus, Micronaut, and Vert.x all inherit. **Runtime assumed:** Java 21+ (LTS) or Kotlin on the JVM. Notes reference OpenJDK/HotSpot defaults. Load order: `mir-backend` → `mir-backend-jvm` → `<framework module>`. ## The JVM footguns AI walks into (framework-agnostic) ### 1. Thread-pool sizing and pool-exhaustion deadlock Platform threads are expensive (≈1 MB stack each by default). The JVM's blocking I/O model means every request that waits on the DB, cache, or downstream HTTP holds a thread. **Little's Law sets the floor:** `threads_needed = throughput_rps × latency_s`. At 500 req/s with 200 ms average latency you need 100 threads just to break even — the JVM default `ForkJoinPool.commonPool()` has only `CPU_cores - 1`. **Pool-exhaustion deadlock** is the silent killer: a pooled request thread submits a subtask to the *same* pool and then `get()`s on the future. If all pool slots are occupied waiting on their own subtasks, no thread is available to run those subtasks — the whole pool gridlocks. Every `.get()` or `join()` inside a thread-pool-backed executor is a suspect. ```jav