# False Sharing And Contended

> Proving and mitigating cache-line false sharing between independent locations with hot writes. Covers ownership and address/layout hypotheses, coherence/HITM evidence limits, JMH topology, arrays and object placement, `@Contended` module/restriction mechanics, grouping and padding, JOL/address validation, manual padding fragility, striping, compact headers, memory cost and cross-socket/NUMA validation. Use after excluding logical contention; cache fundamentals, lock contention and general object sizing have separate owners.

- Skill: `robsonkades/false-sharing-and-contended` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add robsonkades/false-sharing-and-contended`
- Raw SKILL.md: https://api.skillmd.com/api/skills/robsonkades/false-sharing-and-contended/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: robsonkades (https://skillmd.com/u/robsonkades)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/robsonkades/false-sharing-and-contended

---


# False sharing and `@Contended`

## Purpose

Establish that writes invalidate a coherence granule/cache line used by another core for a
different logical variable (writing or reading),
then choose ownership/layout changes whose throughput/latency benefit exceeds memory and maintenance
cost. Cache misses or poor scaling alone do not prove false sharing.

## Ownership boundary

- This skill owns false-sharing hypothesis, layout/placement, `@Contended`, padding and validation.
- `cpu-cache-and-numa` owns cache/coherence/NUMA fundamentals.
- `lock-inflation` and `lock-free-patterns` own logical lock/CAS contention.
- `object-layout-and-footprint` owns general object sizing/header trade-offs.

## Proof contract

```text
independent logical variables/slots, writer ownership and readers:
write/read frequency and production thread/key topology:
actual address offsets/alignment and cache-line size(s):
JDK/layout/header/GC/allocation stability assumptions:
coherence/PMU evidence with support/multiplex/scope:
controlled ownership/layout perturbation:
memory/GC/locality cost and next bottleneck:
```

## Distinguish contention types

| Type                     | Shared meaning                                 | Typical evidence                            | Candidate direction             |
| ------------------------ | ---------------------------------------------- | ------------------------------------------- | ------------------------------- |
| lock contention          | one guarded invariant                          | monitor/park/owner wait                     | reduce/partition guarded work   |
| true data/CAS contention | same logical variable                          | retries/RMW/coherence                       | shard/batch/owner/semantics     |
| false sharing            | different variables on same line               | layout + writers + coherence + perturbation | separate/align ownership/layout |
| capacity/cache locality  | working set misses without writer invalidation | miss/working-set/topology                   | compact/block/localize/prefetch |

Padding true contention does not make the logical hotspot independent.
At least one participant must write; read-only sharing does not create this invalidation
mechanism. Padding and `@Contended` do not add happens-before, visibility or atomicity:
retain required volatile/atomic/locking semantics or explicit ownership and handoff.

## Evidence ladder

1. Localize the scaling/tail/CPU regression and rule out load, locks, CAS hotspot, GC/JIT and I/O.
2. Map writers to independent fields/array slots and their actual runtime layout/address relationship.
3. Collect supported coherence/cache events (for example HITM/snoop variants on some CPUs/tools),
   validating event semantics, multiplexing, skid, process/CPU scope and topology.
4. Apply a controlled separation/ownership perturbation without changing useful semantics/work.
5. Confirm the same production metric improves while memory, GC and locality remain acceptable.

Generic `cache-misses`/LLC misses are not specific and false sharing may manifest as coherence traffic
without the naive counter pattern. A cache-miss flame graph compared with CPU samples is not a
standalone proof.

If PMU access, addresses or placement cannot be verified, report a hypothesis with the
available perturbation evidence and its limits. Do not fabricate zero contention from an
unsupported counter or call a padded speedup alone proof. Return the affected variables,
evidence, proposed change, correctness constraints and measured or pending production check.

## Layout and placement

JOL reports class/instance field layout under its current VM model; it does not by itself prove the
absolute address/alignment of two separately allocated objects over time. Arrays provide predictable
element stride but array base alignment and hardware line size still matter. Derive padding/stride:

```text
stride elements >= ceil(cache-line bytes / element bytes)
```

Then ensure each active slot begins in a separate relevant line, accounting for base offset and
adjacent-line/prefetch behavior where measured. “Stride 8 for long” assumes a 64-byte line and
suitable alignment; it is not universal.

GC can move objects and allocation adjacency is not a stable API. Prefer layout within one object/
array or ownership partition that can be verified, and test the collector/JDK used.

## `@Contended`

`jdk.internal.vm.annotation.Contended` is internal JDK API. Application source normally needs an
appropriate compile-time module export, and HotSpot commonly restricts user-class padding unless
`-XX:-RestrictContended` is enabled. Runtime exports are needed only when application runtime code
must access the internal type; the VM can recognize annotation metadata without a blanket claim that
every run needs `--add-exports`.

Verify on the exact JDK:

- annotation is present in compiled class and applied in runtime layout;
- effective `EnableContended`, `RestrictContended` and padding settings/support;
- field/class contention group semantics;
- actual gaps/offsets and object/array placement;
- memory footprint across number of instances and GC consequence.

Padding width is a spacing policy, not “bytes charged per field” exactly; headers, alignment, groups,
field layout and multiple annotations determine total size. Do not justify a default width with one
microarchitecture's prefetch story as a universal guarantee.

Because this is internal API/flag surface, prefer JDK-supplied striped abstractions or an explicit
layout type when feasible, and include upgrade tests.

## Mitigation framework

| Mechanism                          | Prefer when                                               | Cost/risk                                |
| ---------------------------------- | --------------------------------------------------------- | ---------------------------------------- |
| ownership/confinement then combine | exact combination point exists                            | delayed aggregation/semantics            |
| striping                           | commutative/associative approximate or partitioned update | memory, read aggregation, skew           |
| padded field/class                 | stable hot independent fields                             | footprint, internal API/layout drift     |
| array stride/struct-of-arrays      | indexed owners and stable layout                          | wasted space, alignment/index complexity |
| batch updates                      | delayed visibility acceptable                             | burst/tail/failure semantics             |
| compact layout instead             | read/locality dominates, not writer sharing               | can worsen writer density                |

`LongAdder` scales hot cumulative updates using striped cells, but its sum is not an atomic snapshot.
It is not a drop-in replacement for IDs, exact bounds or balances.

Compact object headers can change density/offsets and therefore both footprint/locality and sharing
risk. Feature status/defaults vary across JDKs. Inspect exact JEP/build/layout and re-run evidence;
do not predict false sharing from header size alone.

## Benchmark design

Use JMH with an explicit shared-state topology and deterministic mapping from worker role to field/
slot. Sweep:

- one writer through expected concurrency/overload;
- core, SMT sibling, socket and NUMA placement;
- reads/writes and production work between updates;
- padded/unpadded/owner-local/striped alternatives;
- exact JDK, collector, header and container CPU configuration.

Preserve raw forks and report useful operations, CPU/op, tail, PMU coverage/events, memory footprint,
allocation/GC and placement. A fixed three-fork rule or expected “magical magnitude” is not validity.

## Failure modes

- annotation ignored/restricted or layout differs after JDK upgrade;
- padding separates fields inside an object but adjacent objects/array slots still share;
- manual dummy fields reordered/grouped or optimized around by layout rules;
- stride miscomputed for line/base alignment;
- striping removes false sharing but hot-key/cell collisions create true contention;
- footprint increase causes cache/GC regression larger than coherence benefit;
- benchmark thread-to-field mapping differs from production;
- PMU event unavailable/multiplexed/virtualized and interpreted as zero contention.

## Anti-patterns

| Anti-pattern                            | Failure                                     | Better approach                               | Narrow exception |
| --------------------------------------- | ------------------------------------------- | --------------------------------------------- | ---------------- |
| LLC misses prove false sharing          | many mechanisms cause misses                | layout + ownership + coherence + perturbation |
| `@Contended` costs exactly 128 B/field  | grouping/alignment/layout vary              | measure actual layout/footprint               |
| Always stride eight longs               | assumes 64-B line/alignment                 | derive and verify target layout               |
| JOL alone proves two objects share      | relative field layout != absolute adjacency | address/topology or controlled array layout   |
| Padding before excluding CAS contention | true shared line remains                    | change semantics/ownership/striping           |
| Production thread count alone           | placement/socket/SMT matters                | validate actual topology distribution         |

## Definition of done

- [ ] Variables are logically independent and writers/topology are mapped.
- [ ] Actual layout/address and cache-line assumptions are validated on target.
- [ ] PMU evidence limitations and a controlled separation test are recorded.
- [ ] Annotation/flag/module/group/padding behavior is verified, not assumed.
- [ ] Throughput/tail gain survives realistic placement/load and correctness tests.
- [ ] Footprint, locality, allocation/GC, upgrade and next-bottleneck costs are acceptable.

## References

- [`@Contended` mechanics and layout](references/contended-mechanics.md) — read when applying the annotation, choosing groups, or checking ignored padding/module access.
- [Proving and fixing false sharing](references/proving-and-fixing.md) — read when designing the separation experiment or interpreting PMU/JMH results.
- [JEP 142: Reduce cache contention on specified fields](https://openjdk.org/jeps/142)
- [OpenJDK `Contended`](https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/jdk/internal/vm/annotation/Contended.java)
- [OpenJDK Striped64](https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/concurrent/atomic/Striped64.java)

