question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. ItΒ collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Factory and Provider Memory Leak

See original GitHub issue

I added LeakCanary to my app, and I’ve been getting reports that any class that uses a factory or provider binding is leaking a reference to a destroyed Activity.

I didn’t look too deeply into it, but it looks like the lambda in Factory.getFactory is capturing the BindingDI instance, which for some reason has a reference to my Activity in its context field. I’m not sure how the activity got set as the context.

I use this scope but nothing in SomethingApi, SomethingManager, nor somethingFactory use it.

There is a class bound in an activitySingleton scope that uses SomethingManager but that’s not referenced in the leak trace, it is bound after SomethingApi, and I’ve verified that it and activityScope has been properly destroyed.

┬───
β”‚ GC Root: System class
β”‚
β”œβ”€ android.provider.FontsContract class
β”‚    Leaking: NO (MyApp↓ is not leaking and a class is never leaking)
β”‚    ↓ static FontsContract.sContext
β”œβ”€ co.my.app.MyApp instance
β”‚    Leaking: NO (Application is a singleton)
β”‚    MyApp does not wrap an activity context
β”‚    ↓ MyApp.kodein
β”‚                     ~~~~~~
β”œβ”€ org.kodein.di.LazyKodein instance
β”‚    Leaking: UNKNOWN
β”‚    ↓ LazyKodein.baseKodein$delegate
β”‚                 ~~~~~~~~~~~~~~~~~~~
β”œβ”€ kotlin.SynchronizedLazyImpl instance
β”‚    Leaking: UNKNOWN
β”‚    ↓ SynchronizedLazyImpl._value
β”‚                           ~~~~~~
β”œβ”€ org.kodein.di.internal.KodeinImpl instance
β”‚    Leaking: UNKNOWN
β”‚    ↓ KodeinImpl._container
β”‚                 ~~~~~~~~~~
β”œβ”€ org.kodein.di.internal.KodeinContainerImpl instance
β”‚    Leaking: UNKNOWN
β”‚    ↓ KodeinContainerImpl.tree
β”‚                          ~~~~
β”œβ”€ org.kodein.di.internal.KodeinTreeImpl instance
β”‚    Leaking: UNKNOWN
β”‚    ↓ KodeinTreeImpl.bindings
β”‚                     ~~~~~~~~
β”œβ”€ java.util.HashMap instance
β”‚    Leaking: UNKNOWN
β”‚    ↓ HashMap.table
β”‚              ~~~~~
β”œβ”€ java.util.HashMap$Node[] array
β”‚    Leaking: UNKNOWN
β”‚    ↓ HashMap$Node[].[89]
β”‚                     ~~~~
β”œβ”€ java.util.HashMap$Node instance
β”‚    Leaking: UNKNOWN
β”‚    ↓ HashMap$Node.value
β”‚                   ~~~~~
β”œβ”€ java.util.ArrayList instance
β”‚    Leaking: UNKNOWN
β”‚    ↓ ArrayList.elementData
β”‚                ~~~~~~~~~~~
β”œβ”€ java.lang.Object[] array
β”‚    Leaking: UNKNOWN
β”‚    ↓ Object[].[0]
β”‚               ~~~
β”œβ”€ org.kodein.di.KodeinDefinition instance
β”‚    Leaking: UNKNOWN
β”‚    ↓ KodeinDefinition.binding
β”‚                       ~~~~~~~
β”œβ”€ org.kodein.di.bindings.Singleton instance
β”‚    Leaking: UNKNOWN
β”‚    ↓ Singleton.scope
β”‚                ~~~~~
β”œβ”€ org.kodein.di.bindings.NoScope instance
β”‚    Leaking: UNKNOWN
β”‚    ↓ NoScope._registry
β”‚              ~~~~~~~~~
β”œβ”€ org.kodein.di.bindings.StandardScopeRegistry instance
β”‚    Leaking: UNKNOWN
β”‚    ↓ StandardScopeRegistry._cache
β”‚                            ~~~~~~
β”œβ”€ java.util.concurrent.ConcurrentHashMap instance
β”‚    Leaking: UNKNOWN
β”‚    ↓ ConcurrentHashMap.table
β”‚                        ~~~~~
β”œβ”€ java.util.concurrent.ConcurrentHashMap$Node[] array
β”‚    Leaking: UNKNOWN
β”‚    ↓ ConcurrentHashMap$Node[].[0]
β”‚                               ~~~
β”œβ”€ java.util.concurrent.ConcurrentHashMap$Node instance
β”‚    Leaking: UNKNOWN
β”‚    ↓ ConcurrentHashMap$Node.val
β”‚                             ~~~
β”œβ”€ org.kodein.di.bindings.SingletonReference$make$1 instance
β”‚    Leaking: UNKNOWN
β”‚    Anonymous subclass of kotlin.jvm.internal.Lambda
β”‚    ↓ SingletonReference$make$1.$value
β”‚                                ~~~~~~
β”œβ”€ co.my.app.api.SomethingApiImpl instance
β”‚    Leaking: UNKNOWN
β”‚    ↓ SomethingApiImpl.somethingManager
β”‚                    ~~~~~~~~~~~~~
β”œβ”€ co.my.app.models.something.SomethingManagerImpl instance
β”‚    Leaking: UNKNOWN
β”‚    ↓ SomethingManagerImpl.somethingFactory
β”‚                        ~~~~~~~~~~~~~
β”œβ”€ org.kodein.di.bindings.Factory$getFactory$1 instance
β”‚    Leaking: UNKNOWN
β”‚    Anonymous subclass of kotlin.jvm.internal.Lambda
β”‚    ↓ Factory$getFactory$1.$kodein
β”‚                           ~~~~~~~
β”œβ”€ org.kodein.di.internal.BindingKodeinImpl instance
β”‚    Leaking: UNKNOWN
β”‚    ↓ BindingKodeinImpl.context
β”‚                        ~~~~~~~
β•°β†’ co.my.app.main.MainActivity instance
​     Leaking: YES (ObjectWatcher was watching this because co.myapp.main.MainActivity received Activity#onDestroy() callback and Activity#mDestroyed is true)

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:7 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
SalomonBryscommented, Aug 20, 2020

Adressed in 9e6afe1535c7d1332f9bf1364ba1e8fdc0a6296e and published as 7.1.0-master-87 in dev repository

0reactions
romainbslcommented, Dec 28, 2020

fixed in 7.2

Read more comments on GitHub >

github_iconTop Results From Across the Web

Factory and Provider Memory Leak Β· Issue #301
My fix is to create another type of NoArgDIBinding that has the deferred behavior of Singleton and the context safe behavior of EagerSingleton...
Read more >
Understanding Memory Leaks in Java
A Memory Leak is a situation where there are objects present in the heap that are no longer used, but the garbage collector...
Read more >
Tackling memory leak - Performance investigations
Memory leak occurs if useless resources are not removed from memory – there has to be something rooting old data. Investigation plan:.
Read more >
8 Ways You can Cause Memory Leaks in .NET
Memory leaks are sneakily bad creatures. It's easy to ignore them for a very long time, while they slowly destroy the application. With...
Read more >
Memory Leak in ServerLocator.factories?
Hi all, We use HornetQ using JMS API in a web application. When a message needs to be sent, we use: con =...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found