Performance Analysis and Optimization of Synchronized Reflection Calls in a Java Backend Service
The article investigates a high‑traffic Java backend issue caused by synchronized reflection calls, analyzes thread‑blocking stack traces, demonstrates the problematic code, and presents a compile‑time PropertyDescriptor optimization that eliminates runtime locking, resulting in significant latency improvements and a deeper understanding of JVM lock mechanisms.
Background: A Java backend service for a travel platform experienced severe latency spikes during high traffic because a reflection utility used PropertyDescriptor which internally invoked synchronized methods, causing many threads to block.
Problem discovery: Slow queries were observed on both PC and mobile list pages. Using QTrace and jstack samples under load revealed numerous threads in the BLOCKED state while waiting for a monitor inside java.beans.Introspector.getPublicDeclaredMethods. The stack traces pointed to ReflectUtils.invokeGetMethod creating a new PropertyDescriptor for each field.
Root cause analysis: Each call to new PropertyDescriptor(fieldName, clazz) triggers a synchronized block inside the JDK’s introspection code, which becomes a bottleneck when many fields (≈60 per product) are accessed concurrently.
Solution: Move the creation of PropertyDescriptor to compile time, pre‑instantiating a descriptor for each field so the runtime no longer performs the synchronized reflection step. The revised code replaces the dynamic creation with a cached descriptor, eliminating the monitor contention.
Performance results: After the change, a load test on six machines with 200 concurrent users showed fetches per second increasing from ~202 to ~306, and average first‑response time dropping from ~958 ms to ~572 ms, demonstrating a clear latency reduction.
Re‑examining synchronized: The article explains that modern JVMs (since JDK 1.6) use biased locking and lightweight locking to reduce the cost of synchronized. It describes the lock acquisition process, safe points, and how the JVM inflates a lock from biased → lightweight → heavyweight when contention occurs.
JVM lock details: Code snippets from HotSpot’s ObjectSynchronizer::fast_enter and ObjectSynchronizer::slow_enter illustrate how the VM checks for bias, attempts CAS operations, and falls back to lock inflation, providing insight into the underlying mechanisms that caused the original performance issue.
References: The article links to several Chinese blog posts that dive deeper into the implementation of synchronized, JDK source compilation, and lock theory.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Qunar Tech Salon
Qunar Tech Salon is a learning and exchange platform for Qunar engineers and industry peers. We share cutting-edge technology trends and topics, providing a free platform for mid-to-senior technical professionals to exchange and learn.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
