Skip to content

Avoid Hint allocation in Scope.addBreadcrumb when no beforeBreadcrumb callback #5685

Description

@runningcode

Problem

Scope.addBreadcrumb(Breadcrumb, Hint) allocates a Hint unconditionally when the caller passes null:

if (hint == null) {
  hint = new Hint();
}
SentryOptions.BeforeBreadcrumbCallback callback = options.getBeforeBreadcrumb();
if (callback != null) {
  breadcrumb = executeBeforeBreadcrumb(callback, breadcrumb, hint);
}

The Hint is only ever used to pass to the beforeBreadcrumb callback — the scope observers receive addBreadcrumb(crumb) without it. So when no beforeBreadcrumb callback is configured (the common case), the Hint is created and immediately discarded.

new Hint() is not free: it allocates a HashMap (internalStorage), an ArrayList (attachments), and an AutoClosableReentrantLock — 3+ objects per breadcrumb.

Evidence

From on-device method trace analysis (median.perfetto-trace, foodpanda dev app under Macrobenchmark): Scope#addBreadcrumb main-thread self-time was ~16ms across 65 breadcrumbs. Per-call cost is sub-ms, but the wasted allocation scales with breadcrumb volume and adds GC pressure across the whole app lifetime.

Fix

Only allocate the Hint when a beforeBreadcrumb callback is actually set:

SentryOptions.BeforeBreadcrumbCallback callback = options.getBeforeBreadcrumb();
if (callback != null) {
  if (hint == null) {
    hint = new Hint();
  }
  breadcrumb = executeBeforeBreadcrumb(callback, breadcrumb, hint);
}

Pure allocation elimination, no behavior change.

Acceptance

No Hint allocation on the addBreadcrumb path when beforeBreadcrumb is unset; existing breadcrumb tests still pass.

Metadata

Metadata

Assignees

Fields

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