firebase / firebase-android-sdk

Firebase Android SDK
https://firebase.google.com
Apache License 2.0
2.28k stars 578 forks source link

Memory leak in FirebaseInAppMessagingDisplay #5076

Open jkozal opened 1 year ago

jkozal commented 1 year ago

[READ] Step 1: Are you in the right place?

Yes

[REQUIRED] Step 2: Describe your environment

[REQUIRED] Step 3: Describe the problem

Steps to reproduce:

Install LeakCanary and Firebase In App Messaging in the project. Launch the app. Wait for the leak notification to appear. LeakCanary is reporting a memory leak for FirebaseInAppMessagingDisplay. Here is part of the leak report:

┬───
│ GC Root: System class
│
├─ android.provider.FontsContract class
│    Leaking: NO (DriverApplication↓ is not leaking and a class is never leaking)
│    ↓ static FontsContract.sContext
├─ some.app.DriverApplication instance
│    Leaking: NO (Application is a singleton)
│    mBase instance of android.app.ContextImpl
│    ↓ Application.mActivityLifecycleCallbacks
│                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~
├─ java.util.ArrayList instance
│    Leaking: UNKNOWN
│    Retaining 403 B in 19 objects
│    ↓ ArrayList[4]
│               ~~~
├─ com.google.firebase.inappmessaging.display.FirebaseInAppMessagingDisplay instance
│    Leaking: UNKNOWN
│    Retaining 456.4 kB in 8619 objects
│    application instance of some.app.DriverApplication
│    ↓ FirebaseInAppMessagingDisplay.imageLoader
│                                    ~~~~~~~~~~~
├─ com.google.firebase.inappmessaging.display.internal.FiamImageLoader instance
│    Leaking: UNKNOWN
│    Retaining 455.5 kB in 8584 objects
│    ↓ FiamImageLoader.tags
│                      ~~~~
├─ java.util.HashMap instance
│    Leaking: UNKNOWN
│    Retaining 455.5 kB in 8583 objects
│    ↓ HashMap["HomeActivity"]
│             ~~~~~~~~~~~~~~~~
├─ java.util.HashSet instance
│    Leaking: UNKNOWN
│    Retaining 447.5 kB in 8434 objects
│    ↓ HashSet[element()]
│             ~~~~~~~~~~~
├─ com.google.firebase.inappmessaging.display.FirebaseInAppMessagingDisplay$4 instance
│    Leaking: UNKNOWN
│    Retaining 447.4 kB in 8430 objects
│    Anonymous subclass of com.google.firebase.inappmessaging.display.internal.FiamImageLoader$Callback
│    val$activity instance of some.app.home.HomeActivity with mDestroyed = true
│    ↓ FirebaseInAppMessagingDisplay$4.val$activity
│                                      ~~~~~~~~~~~~
╰→ some.app.home.HomeActivity instance
​     Leaking: YES (ObjectWatcher was watching this because some.app.home.HomeActivity received
​     Activity#onDestroy() callback and Activity#mDestroyed is true)
​     Retaining 440.0 kB in 8306 objects
​     key = f3ad578b-7adc-416f-87d8-46bbb060e66e
​     watchDurationMillis = 5454
​     retainedDurationMillis = 454
​     mApplication instance of some.app.DriverApplication
​     mBase instance of androidx.appcompat.view.ContextThemeWrapper

METADATA

Build.VERSION.SDK_INT: 33
Build.MANUFACTURER: Google
LeakCanary version: 2.11
App process name: some.app
Class count: 35245
Instance count: 248240
Primitive array count: 158202
Object array count: 37703
Thread count: 91
Heap total bytes: 34959895
Bitmap count: 30
Bitmap total bytes: 766474
Large bitmap count: 0
Large bitmap total bytes: 0
Db 1: open /data/user/0/some.app/databases/com.google.android.datatransport.events
Db 2: closed /data/user/0/some.app/databases/google_app_measurement_local.db
Db 3: open /data/user/0/some.app/no_backup/androidx.work.workdb
Db 4: open /data/user/0/some.app/databases/leaks.db
Db 5: closed /data/user/0/some.app/databases/google_app_measurement_local.db
Db 6: closed /data/user/0/some.app/databases/google_app_measurement_local.db
Db 7: closed /data/user/0/some.app/databases/google_app_measurement_local.db
Db 8: closed /data/user/0/some.app/databases/google_app_measurement_local.db
Count of retained yet cleared: 14 KeyedWeakReference instances
Stats: LruCache[maxSize=3000,hits=123669,misses=242264,hitRate=33%]
RandomAccess[bytes=12113847,reads=242264,travel=105517108805,range=41605070,size=50779357]
Analysis duration: 18044 ms
google-oss-bot commented 1 year ago

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

argzdev commented 1 year ago

Hi @jkozal, thanks for reporting.

Update: I'm able to reproduce the issue now. I guess it takes a while before the leak comes out. I'll notify our engineers and see what we can do here.

Notes: I noticed that the leak only appears when receiving an in-app message with images. Testing with other message layout that does not include an image will not show the same behavior.