Features
- Use Android's
ProfilingManager(Perfetto) for continuous profiling on API 35+ devices (#5251)- On API 35+ devices, continuous profiling now automatically uses Android's system
ProfilingManagerwith Perfetto-based stack sampling, providing lower-overhead and more accurate profiles. No configuration change is required. - Devices below API 35 keep using the legacy
Debug-based profiler. - Added an
enableLegacyProfilingoption (defaulttrue) to disable the legacyDebug-based profiler. Setting it tofalsedisables continuous profiling on API < 35 devices as well as transaction-based profiling (profilesSampleRate/profilesSampler) on all devices, since transaction-based profiling is not supported by Perfetto. - It can also be configured via the
io.sentry.profiling.enable-legacy-profilingmanifest flag. - See the Android profiling docs for details.
- On API 35+ devices, continuous profiling now automatically uses Android's system
Behavioral Changes
- The outbox and cache directories are no longer created by
Sentry.init(#5792)- They are now created lazily by whichever component first writes into them, off the init thread. As a result, the directories at
SentryOptions.getOutboxPath()andSentryOptions.getCacheDirPath()are not guaranteed to exist onceSentry.initreturns. - If you write envelopes into the outbox path yourself instead of going through the SDK — as hybrid SDKs do for
captureEnvelope— create the directory first, e.g.new File(outboxPath).mkdirs().
- They are now created lazily by whichever component first writes into them, off the init thread. As a result, the directories at
Improvements
- Skip building Android manifest metadata debug log messages when debug logging is disabled, reducing allocations during SDK init (#5790)
Fixes
- Use the original app build's ProGuard UUID for ANR profile chunks (#5852)
- Fix potential ANR/deadlock in Session Replay when
checkCanRecordruns on the replay executor thread (#5837) - Prevent concurrent PixelCopy access during Session Replay masking and bitmap cleanup (#5808)
- Release
MediaMuxerwhen the replay video encoder fails to start to avoid a resource leak (#5607) - Set the correct platform (
androidinstead ofjava) on ANR profile chunks so they are billed as UI Profile Hours rather than Continuous Profile Hours (#5836) - Skip encoding and capturing buffered session replay segments while rate-limited, so we don't waste resources on envelopes the transport will drop (#5813)
- These skipped replays are now reported as
ratelimit_backoffdiscarded events in client reports, so they no longer disappear from drop statistics. One event is recorded per buffer flush rather than per segment. - Buffer mode is also kept while rate-limited instead of switching to session mode, so the rolling buffer stays warm and the next error after the rate limit expires can send a complete replay.
- These skipped replays are now reported as
Performance
- Create the outbox and cache directories lazily in their consumers instead of during SDK init, moving the
mkdirs()calls off the init (main) thread (#5792) - Reduce the number of SDK threads:
LifecycleWatchernow schedules the session-end task on the shared timer executor instead of creating a dedicatedjava.util.Timerthread (#5819) - Reduce the number of SDK threads:
RateLimiternow schedules its rate-limit-lifted notifications on the shared timer executor instead of creating a dedicatedjava.util.Timerthread (#5814) - Speed up deserialization of arbitrary JSON objects by typing numbers without throwing exceptions (#5783)