Detect and resolve false sharing in Java on Arm Neoverse
Introduction
Understand false sharing in Java
Create and inspect the baseline
Identify the contended cache line
Add @Contended and verify contention padding
Compare baseline and padded runtimes
Next steps
Detect and resolve false sharing in Java on Arm Neoverse
Understand the cache-line effect
Caches transfer data between CPU cores and maintain coherence at the granularity of cache lines.
When one core writes to a location, the coherence protocol generally grants it exclusive ownership of the complete line and invalidates copies held by other cores. A 64-byte cache line is common on Arm Neoverse-based servers, but the line size is implementation-dependent.
Processors maintain cache coherence for complete cache lines rather than individual Java objects or fields. The Java Virtual Machine (JVM) determines field layout, while the allocator determines where an object resides in the heap. A moving garbage collector can later relocate it. As a result, one cache line can contain fields from one object or parts of multiple objects.
Cache-line sharing occurs when multiple cores access data in the same cache line and at least one access is a write.
True sharing occurs when threads communicate through the same variable. False sharing occurs when threads access different variables that occupy the same cache line. The Java program treats the variables as independent, but the hardware still maintains coherence for their common cache line.
False sharing transfers ownership of the complete cache line
Java applications can encounter false sharing in three common forms:
- Independently written fields within one object
- Independently allocated objects placed on the same line
- Array elements updated by different workers
The following factors influence the result:
- Object headers
- Inheritance
- Compressed references
- Field layout
- Object alignment
- Allocation order
- Garbage collection
Understand the performance effect
When workers on different cores repeatedly write independent values in one cache line, ownership of the line can move between their caches. The cores can spend more time waiting for coherence transactions, even though the Java variables don’t logically interact. This can increase latency and limit multithreaded throughput.
Field adjacency makes false sharing possible, but it doesn’t prove that false sharing occurs. Object placement, thread placement, workload duration, and the processor all affect the observed behavior.
What you’ve learned and what’s next
You’ve now learned about cache-line and performance effects of Java false sharing.
Next, you’ll create the baseline example and use Java Object Layout (JOL) to inspect field offsets and Perf C2C to observe baseline cache-line sharing.