Skip to content

Reduce AutoClosableReentrantLock allocation churn during init #5642

Description

@runningcode

Problem

Many SDK classes hold a per-instance io.sentry.util.AutoClosableReentrantLock (created eagerly in field initializers). There are ~66 new AutoClosableReentrantLock() sites across 54 files in sentry + sentry-android-core, so constructing the SDK's object graph during SentryAndroid.init allocates a lot of locks.

From the customer-provided Perfetto trace (sentryinvest), inside the SentryAndroid.init subtree:

  • java.util.concurrent.locks.ReentrantLock.<init>81 instances created
  • ReentrantLock$Sync.<init> — 81 (~8.7 ms self, btrace-inflated) + NonfairSync.<init> 81 (~1.3 ms)
  • plus acquire/lock/unlock/tryRelease overhead on the init path

Each ReentrantLock also allocates an AbstractQueuedSynchronizer subclass (Sync), so this is both allocation pressure (GC) and CPU on the main thread at init.

Context / constraint

These locks exist because synchronized was replaced with ReentrantLock (#3715) to avoid virtual-thread pinning (Loom). So reverting to synchronized is not the goal — we want to keep the Loom-friendly behavior while reducing the eager allocation.

Possible directions

  • Lazy-allocate the lock — only create the underlying ReentrantLock on first acquire(), so objects that never lock during init (the common case for many of these) don't allocate one. AutoClosableReentrantLock is the single chokepoint, so this could be a localized change.
  • Audit hot init objects — for objects created during init that don't actually need synchronization (or are effectively single-threaded at construction), drop the lock.
  • Measure GC impact via Kiln in addition to the init main-thread time.

Acceptance

Fewer ReentrantLock allocations during SentryAndroid.init (verify via on-device ART trace / Kiln), with no change to thread-safety semantics.

Metadata

Metadata

Assignees

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions