android / android/identity-samples

Persistent Memory Leak in CredentialManager with LoginActivity

Open
#186 0 comments 6 reactions 0 assignees View on GitHub
Dominant language
Kotlin
Stars
515
Forks
283
Avg merge
9h 37m
Merged PRs (30d)
2

Description

Description

We are experiencing a persistent memory leak in our Android application when using CredentialManager within a LoginActivity. The LoginActivity instance is being retained in memory
after it has been destroyed, as consistently reported by LeakCanary. The leak is always traced back to CredentialManager$GetCredentialTransport holding a reference to the activity's
context.

We have implemented several standard fixes for this type of leak, including using lifecycleScope for coroutines, implementing getCredentialAsync with a CancellationSignal that is
cancelled in onDestroy(), and ensuring that no strong references to the activity are held in callbacks. Unfortunately, none of these measures have resolved the issue. This leads us
to believe there may be an underlying bug in the androidx.credentials library.

Steps to Reproduce

1. Create a LoginActivity that uses CredentialManager.create(context) and credentialManager.getCredentialAsync(...).
2. Launch the LoginActivity.
3. Trigger the getCredentialAsync flow.
4. Close or navigate away from the activity.
5. Observe the memory leak reported by LeakCanary.

┬───
│ GC Root: Global variable in native code

├─ android.credentials.CredentialManager$GetCredentialTransport instance
│ Leaking: UNKNOWN
│ Retaining 658.5 kB in 6309 objects
│ mContext instance of in.aakhor.aakhorai.LoginActivity with mDestroyed = true
│ ↓ CredentialManager$GetCredentialTransport.mContext
│ ~~~~~~~~
╰→ in.aakhor.aakhorai.LoginActivity instance
Leaking: YES (ObjectWatcher was watching this because in.aakhor.aakhorai.LoginActivity received
Activity#onDestroy() callback and Activity#mDestroyed is true)
Retaining 656.9 kB in 6300 objects

Contributor guide

Open the contributing guide

Research direction

Start with the LoginActivity reproduction using CredentialManager.create(context), getCredentialAsync, cancellation, and LeakCanary, then inspect the reported CredentialManager$GetCredentialTransport.mContext retention path. Done means confirming whether the leak is in the AndroidX Credentials library and documenting a reproducible diagnosis or validated fix; no repository file or test is named.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, kotlin
Domain
authentication, mobile
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.