Skip to content

fix: Removes messageQueue since produces memory leaks #576

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

gmazzo
Copy link
Contributor

@gmazzo gmazzo commented May 5, 2025

Summary

Removes the (unnecessary?) private ConcurrentHashMap<Message, Boolean> messageQueue field and all its associated logic in BaseHandler, since it was identified by us (with LeakCanary) as the root cause of memory leaks when using DialogFragment.

After inspecting the whole code, that logic is a NO-OP since it's only used by AccessUtils.getUploadHandlerMessageQueue(), a method that is not getting called anywhere, probably a legacy code.

The leak is produced when a sendMessageAtTime method is invoked by AndroidX DialogFragment's internal logic. Since this specialized version of Handler stores Messages in a map, the whole tree is retained, producing the leak.

Unless we have missed something, messageQueue is not adding any value, therefore, there is no point in keeping it.

Note

Integration tests need to be cleanup as well mParticle/crossplatform-sdk-tests#44

LeakCanary report

┬───
│ GC Root: Thread object
│
├─ Ik instance
│    Leaking: NO (PathClassLoader↓ is not leaking)
│    Thread name: 'CleanupReference'
│    ↓ Thread.contextClassLoader
├─ dalvik.system.PathClassLoader instance
│    Leaking: NO (MParticle↓ is not leaking and A ClassLoader is never leaking)
│    ↓ ClassLoader.runtimeInternalObjects
├─ java.lang.Object[] array
│    Leaking: NO (MParticle↓ is not leaking)
│    ↓ Object[733]
├─ com.mparticle.MParticle class
│    Leaking: NO (a class is never leaking)
│    ↓ static MParticle.instance
│                       ~~~~~~~~
├─ com.mparticle.MParticle instance
│    Leaking: UNKNOWN
│    Retaining 129 B in 5 objects
│    mAppContext instance of com.glovoapp.HiltUiTestApp_Application
│    ↓ MParticle.mIdentityApi
│                ~~~~~~~~~~~~
├─ com.mparticle.identity.IdentityApi instance
│    Leaking: UNKNOWN
│    Retaining 16.7 kB in 577 objects
│    mContext instance of com.glovoapp.HiltUiTestApp_Application
│    ↓ IdentityApi.mMainHandler
│                  ~~~~~~~~~~~~
├─ com.mparticle.b instance
│    Leaking: UNKNOWN
│    Retaining 2.7 kB in 91 objects
│    ↓ b.c
│        ~
├─ java.util.concurrent.ConcurrentHashMap instance
│    Leaking: UNKNOWN
│    Retaining 2.7 kB in 90 objects
│    ↓ ConcurrentHashMap[key()]
│                       ~~~~~~~
├─ android.os.Message instance
│    Leaking: UNKNOWN
│    Retaining 2.5 kB in 87 objects
│    Message.what = 68
│    Message.when = 0 (6963473 ms before heap dump)
│    Message.obj = instance @322539720 of androidx.fragment.app.DialogFragment$2
│    Message.callback = null
│    Message.target = instance @322539736 of android.app.Dialog$ListenersHandler
│    ↓ Message.obj
│              ~~~
├─ androidx.fragment.app.DialogFragment$2 instance
│    Leaking: UNKNOWN
│    Retaining 2.4 kB in 84 objects
│    Anonymous class implementing android.content.DialogInterface$OnCancelListener
│    ↓ DialogFragment$2.this$0
│                       ~~~~~~
╰→ com.glovoapp.dialogs.OverlayProgressDialog instance
​     Leaking: YES (ObjectWatcher was watching this because com.glovoapp.dialogs.OverlayProgressDialog received Fragment#onDestroy() callback. Conflicts with Fragment.mLifecycleRegistry.state is INITIALIZED)
​     Retaining 2.4 kB in 83 objects
​     key = b09aba74-9150-412d-ab65-e56f4cd0efee
​     watchDurationMillis = 121257
​     retainedDurationMillis = 116245

522156 bytes retained by leaking objects
Signature: 05465ea5398979c4969c38a4a281600e9ab2b643

Testing Plan

  • Was this tested locally? If not, explain why.
  • Ran ./gradlew build locally and it has been successful.

@gmazzo gmazzo changed the base branch from main to development May 5, 2025 10:10
@gmazzo gmazzo force-pushed the fix/remove-leaking-handler branch from d40a2d6 to 997cad4 Compare May 5, 2025 10:11
@Mansi-mParticle Mansi-mParticle force-pushed the fix/remove-leaking-handler branch from 997cad4 to e88de19 Compare May 30, 2025 14:30
@rmi22186 rmi22186 requested a review from Mansi-mParticle May 30, 2025 14:46
Copy link
Collaborator

@Mansi-mParticle Mansi-mParticle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@Mansi-mParticle Mansi-mParticle merged commit 5a2c35a into mParticle:development May 30, 2025
14 of 15 checks passed
mparticle-automation added a commit that referenced this pull request May 30, 2025
## [5.64.0](v5.63.0...v5.64.0) (2025-05-30)

### Features

* Fire Identify if Provided Email in Rokt SelectPlacements ([#578](#578)) ([8325080](8325080))

### Bug Fixes

* Removes `messageQueue` since produces memory leaks ([#576](#576)) ([5a2c35a](5a2c35a))

### Updates & Maintenance

* Migrate Internal listeners class to kotlin ([#548](#548)) ([de96056](de96056))
* Update submodules ([5ffd95f](5ffd95f))
@mparticle-automation
Copy link
Collaborator

🎉 This PR is included in version 5.64.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants