Detect Leaked Subscriptions in RxJava code using RxDisposableWatcher

Andrey Fomenkov
3 min readJan 4, 2021

The Problem

Sometimes it’s possible to forget about releasing a Disposable resource in RxJava code. Consider the following code snippet:

Error handling, subscribeOn(…) and observeOn(…) operators are omitted for simplicity.

As mentioned in the comment, the subscription has not been destroyed later. Of course this is legal only in case it was done intentionally and consciously.
Otherwise it can blow up application logic or cause a memory leak! 💩

Discover leaks with RxDisposableWatcher 🐞

RxDisposableWatcher is a debug tool for monitoring not destroyed Disposable subscriptions in RxJava code. The output exhaustive report in HTML format:

Everything we need: stack trace, number of calls & Observable types.

The report shows up a list of all Rx subscriptions currently alive in application. For example, if during Activity destroy some of them are not being released as expected, then probably it’s a bug. The plugin will help to deal with them.

Setup

At first please visit the project on GitHub for more information:

Plugin usage is very simple (example for Android):

Write report string value to HTML file somewhere on Android SD card, pull to the desktop and finally display in a browser. 🔥 That’s it! 🔥

Typical usage example

Let’s find a leak in the following weather application on Android:

Meanwhile inside WeatherActivity:

Move from CityListActivity toWeatherActivity and back 7 times, then build a report. All records are sorted by calls number. One item is suspicious:

Gotcha! There are 7 alive subscriptions created by WeatherActivity at line 9

Even though theWeatherActivity has been finished, we are still observing ℃ value from Thermometer instance! The report says that subscription has been made in WeatherActivity at line 9.

Solution:

Dispose a resource in onDestroy()

Consider CompositeDisposable for releasing multiple Disposables at once.

Get a report in one click from Android Studio 😳

I want a magic button in Android Studio to display HTML report in one click. Well, the idea is pretty simple:

It consists of three components:
[1] Shell script to send broadcast event, pull report and display in a browser;
[2] BroadcastReceiver event handler in Android application;
[3] The magic button itself.

[ 1 ] Shell script

The script is well commented. Update variables with your own values!

Download the script here. Also make it executable with chmod +x report.sh

[ 2 ] BroadcastReceiver event handler

Register BroadcastReceiver in onCreate() of your Application class:

[ 3 ] Adding a magic button to Android Studio toolbar

Looks very nice, isn’t it? ☝️

First of all create custom action in Android Studio with External Tools:

Preferences → Tools → External Tools

Then add a new button. Right-click on the main toolbar → Customize Menus and Toolbars…Main Toolbar section. Choose action and icon for button:

Now after all proper configurations click on the magic button and you’ll see the generated HTML report in a desktop browser 🥳🎉

References

I suggest this post for reading by Marcin Robaczyński:
📖 How to leak memory with Disposables in RxJava2
On StackOverflow:
📖 Q: Why Rxjava could cause memory leaking?

In case of question you can get in touch with me on Twitter.
RxDisposableWatcher is yet another debugging tool to make your project bug free.

Have a nice day!

--

--