Skip to content

fix: Release leaked JNI references in _AndroidReplayHandler #3633

@buenaflor

Description

@buenaflor

Summary

_AndroidReplayHandler (the isolate-side replay screenshot handler) leaks JNI object references in three places.

Details

1. Bitmap$Config.ARGB_8888 leaks on every bitmap creation

https://github.com/getsentry/sentry-dart/blob/a7f011a3/packages/flutter/lib/src/native/java/android_replay_recorder.dart#L134

_bitmap ??= native.Bitmap.createBitmap$10(
    item.width, item.height, native.Bitmap$Config.ARGB_8888);

Bitmap$Config.ARGB_8888 is a static getter that returns a new JNI reference each call (the generated binding comments say "must be released after use"). This reference is passed to createBitmap$10 and then abandoned — it leaks every time a new bitmap is created (first capture, and on every dimension change).

2. _bitmap never released on isolate shutdown

https://github.com/getsentry/sentry-dart/blob/a7f011a3/packages/flutter/lib/src/native/java/android_replay_recorder.dart#L98

The cached Bitmap is released when dimensions change (line 126), but when the worker isolate shuts down the bitmap is abandoned without releasing.

3. _nativeReplay never released on isolate shutdown

https://github.com/getsentry/sentry-dart/blob/a7f011a3/packages/flutter/lib/src/native/java/android_replay_recorder.dart#L99-L103

The ReplayIntegration JObject obtained in the constructor is stored as a field but never released.

Root cause

WorkerHandler has no close() lifecycle callback. When the isolate receives the shutdown command, it closes the ReceivePort without giving the handler a chance to release resources.

Suggested fix

  1. Add a FutureOr<void> close() method to WorkerHandler (default no-op)
  2. Call handler.close() in runWorker before closing the inbox on shutdown
  3. Override close() in _AndroidReplayHandler to release _bitmap and _nativeReplay
  4. Release the Bitmap$Config.ARGB_8888 reference after passing it to createBitmap$10

Metadata

Metadata

Assignees

No one assigned
    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