You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
perf: Avoid per-transaction Timer thread in SentryTracer (JAVA-596) (#5670)
* perf: Avoid per-transaction Timer thread in SentryTracer (JAVA-570)
Transactions with an idle or deadline timeout each created a
java.util.Timer, which spawns a thread synchronously on the calling
thread (often the main thread on Android). At scale (screen loads, HTTP
spans) this was the dominant source of SDK thread churn.
Schedule the idle/deadline timeouts on a dedicated, shared
ISentryExecutorService held by SentryOptions instead, so no thread is
created per transaction. It is kept separate from the main executor so
timeout callbacks (which finish transactions) don't contend with cached
event sending, and it is not prewarmed: its single worker thread is
spawned lazily on the first scheduled timeout and reused thereafter. The
dedicated executor uses removeOnCancelPolicy so cancelled timeouts (idle
timers are rescheduled per child span) don't accumulate in its queue. On
finish only the scheduled futures are cancelled; the executor is closed
with the SDK.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* changelog
* fix(core): Keep timer executor alive across SDK restart (JAVA-570)
The shared timer executor introduced for transaction idle/deadline
timeouts was shut down on every Scopes.close(), including SDK restart.
This cancelled the pending idle timeout of any transaction started
before the restart (e.g. an in-flight activity transaction), so it
never auto-finished and its envelope was never sent.
Only close the timer executor on a full close, not on restart, matching
the pre-existing per-transaction Timer behaviour. Enable core-thread
timeout on the timer executor so the instance abandoned by a restart
self-terminates once idle instead of leaking a thread.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* refactor(core): Look up shared timer executor on demand (JAVA-570)
SentryTracer cached the shared timer executor in a field for the
lifetime of the transaction. Replace that field with a boolean flag
tracking whether timeouts may still be scheduled, and fetch the
executor from the options each time one is scheduled. This ensures the
tracer always uses the executor currently held by the options (e.g. the
fresh one installed after an SDK restart) rather than a stale reference.
Also make the timer executor's keep-alive duration a constructor
argument backed by the named TIMER_KEEP_ALIVE_SECONDS constant, and
raise it from 10s to 30s so the shared worker thread is less likely to
be torn down and respawned between transactions under normal use.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: CHANGELOG.md
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -35,6 +35,10 @@
35
35
- Prevent logs and metrics from remaining queued after a flush scheduling race ([#5756](https://github.com/getsentry/sentry-java/pull/5756))
36
36
- Fix main thread identification for tombstone (native crash) events ([#5742](https://github.com/getsentry/sentry-java/pull/5742))
37
37
38
+
### Performance
39
+
40
+
- Schedule transaction idle/deadline timeouts on a shared, dedicated executor instead of spawning a `Timer` thread per transaction ([#5670](https://github.com/getsentry/sentry-java/pull/5670))
41
+
38
42
### Dependencies
39
43
40
44
- Bump OpenTelemetry to support Spring Boot 4.1 ([#5573](https://github.com/getsentry/sentry-java/pull/5573))
0 commit comments