I wrote a basic bound service based on the Android documentation, but LeakCanary is telling me the service is leaking.
class LocalService : Service() {
private val binder = LocalBinder()
private val generator = Random()
val randomNumber: Int
get() = generator.nextInt(100)
inner class LocalBinder : Binder() {
fun getService(): LocalService = this@LocalService
}
override fun onBind(intent: Intent): IBinder {
return binder
}
override fun onDestroy() {
super.onDestroy()
LeakSentry.refWatcher.watch(this) // Only modification is to add LeakCanary
}
}
If I bind to the service from an activity as follows, LeakCanary detects the service has leaked
class MainActivity: Activity() {
private var service: LocalService? = null
private val serviceConnection = object: ServiceConnection {
override fun onServiceConnected(name: ComponentName?, binder: IBinder?) {
service = (binder as LocalBinder).getService()
}
override fun onServiceDisconnected(name: ComponentName?) {
service = null
}
}
override fun onStart() {
super.onStart()
bindService(Intent(this, LocalService::class.java), serviceConnection, BIND_AUTO_CREATE)
}
override fun onStop() {
super.onStop()
service?.let {
unbindService(serviceConnection)
service = null
}
}
}
┬
├─ com.example.serviceleak.LocalService$LocalBinder
│ Leaking: NO (it's a GC root)
│ ↓ LocalService$LocalBinder.this$0
│ ~~~~~~
╰→ com.example.serviceleak.LocalService
Leaking: YES (RefWatcher was watching this)
Using Window's Resource Monitor To find a memory leak, you've got to look at the system's RAM usage. This can be accomplished in Windows by using the Resource Monitor. In Windows 11/10/8.1: Press Windows+R to open the Run dialog; enter "resmon" and click OK.
A memory leak is bad because it blocks memory resources and degrades system performance over time. If not dealt with, the application will eventually exhaust its resources, finally terminating with a fatal java. lang.
DEFINITION A memory leak is the gradual deterioration of system performance that occurs over time as the result of the fragmentation of a computer's RAM due to poorly designed or programmed applications that fail to free up memory segments when they are no longer needed.
I don't know if it's late to answer but after reading your question I also setup leakCanary in my project and found this leak. I was sure that it's because of the inner binder class which is holding the reference of outer class which is service here. That is why in your leak log it shows LocationService is leaking. I found a solution by @commonsguy here and implemented the solution with a bit simpler example here. Hope this helps. Keep coding, stay blessed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With