Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bound service leaks memory

I wrote a basic bound service based on the Android documentation, but LeakCanary is telling me the service is leaking.

  1. Is there a leak or have I misconfigured LeakCanary?
  2. How can I write a bound service that does not leak?

The Code

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)
like image 454
Enrico Avatar asked May 22 '19 08:05

Enrico


People also ask

How do I find out what is causing my memory leak?

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.

How serious are memory leaks?

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.

What are memory leaks?

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.


1 Answers

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.

like image 145
Rookie Avatar answered Oct 03 '22 14:10

Rookie