eclipse-paho / eclipse-paho/paho.mqtt.java

close() v.s. unregisterResources() - OutOfMemory Exception

Open
#747 4 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
2.3k
Forks
919
PR merge metrics
No merged PRs in 30d

Description

- [x] Bug exists Release Version 1.2.2 ( Master Branch)
- [ ] Bug exists in MQTTv3 Client on Snapshot Version 1.2.3-SNAPSHOT (Develop Branch)
- [ ] Bug exists in MQTTv5 Client on Snapshot Version 1.2.3-SNAPSHOT (Develop Branch)

Whenever I encounter an error in the paho MQTT client, I attempt a reconnect 60 seconds later:

```
override fun connectionLost(cause: Throwable) {
LOG.e("Connection Lost :: $cause")
cleanupClient()
retry { connect() }
}

private fun cleanupClient(){
try {
for (i in topicList.indices) {
client!!.unsubscribe(topicList[i])
}
client!!.close()
client = null
} catch (e: Exception) {
LOG.e("Could not clean up!", e)
}
}

fun retry(cb: () -> Unit){
handler.removeCallbacksAndMessages(null)
handler.postDelayed({
cb()
}, 60000)
}
```
So if the app is sitting without internet, it will continuously attempt to reconnect until it finally does. The issue is that after a few hundred attempts (a couple hours), the app crashed with an Out of Memory Issue:

> java.lang.OutOfMemoryError: OutOfMemoryError thrown while trying to throw OutOfMemoryError; no stack available

I only have 2 class-global variables, my handler and my MqttAndroidClient:

```
private var client: MqttAndroidClient? = null

// For retries
val handler = Handler()
```

And of those, only the client is ever re-assigned a value. My understanding is that in the clean up function, because I close and null out the client, the JVM should clean up my resources. The documentation for client.close():

> Close the client. Releases all resource associated with the client. After the client has been closed it cannot be reused. For instance attempts to connect will fail.

There is also another function called unregisterResources()

> Unregister receiver which receives intent from MqttService avoids IntentReceiver leaks.

It seems to me that only client.close() needs to be called, but I'm unsure if this will cause other issues.

And if there is anything else that you would suggest that I look at, I would love your advice!

I cross posted this from the android page because there hasn't been a response on the android forum since November. I hope that is alright, and thank you for your help in advance!

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.