Virtual Thread Pinning: How a Silent JVM Bug Caps Your App's Throughput
Java's virtual threads, introduced via Project Loom, can silently revert to behaving like a bounded thread pool due to a phenomenon called 'pinning,' where a virtual thread cannot unmount from its carrier OS thread during a blocking operation. This occurs in exactly two scenarios: blocking inside a synchronized block (in JDK 21–23) and blocking within native or JNI frames, the latter remaining unfixed even in JDK 24. When pinning occurs repeatedly in a hot code path, all carrier threads — limited by default to the number of CPU cores — can stall simultaneously, causing scheduler starvation that mimics a deadlock from the outside. JDK 24 resolves the synchronized pinning issue by decoupling object monitors from carrier threads, but native frame pinning persists and can hide in unexpected places like static initializers. Developers are advised to audit blocking calls inside synchronized methods and third-party libraries, and use JVM diagnostics to detect pinning before it silently degrades throughput.
This is an AI-generated summary. ShortSingh links to the original source for the complete article.
Discussion (0)
Log in to join the discussion and vote.
Log in