Memory leak
supervital opened this issue · comments
Hi Kaushik, thanks for yours examples about RxJava. I`ve just started learning it. I investigated RxJava with Retrofit, and found an issue. When the request being done to server, an exception is thrown with 403 error. onError called, an exception logged. looks Ok.
The issue is - when I close the app with back button, and open again, and do the request again, exception is thrown, and 2 errors was logged. Do the same steps, onError was called, 3 erros was logged, etc. Memory leak occurs.
Firstly - it seems strange, the Observable finished with an error, onError was called, app was closed with back button, onDestroy was called, all objects should be garbage collected.Isn't it ?
Ok, I tried to call unsubscribe on OnDestroy, the issue still reproduce.
I googled the issue and found workaround using WeakReference. It looks awkwardly.
What is your opinion about this ? Or, I did something wrong ?
Hiya.
Sure let's try to break it down and get to the bottom of the issue.
The first problem you described seems like your not unsubscribing from the
observable at the end of the life cycle. Help me answer these questions:
- Did you pull the latest code from the repo? (I recently pushed some
fixes) - Which example specifically are you trying ? Give me the name of the
class from the sample repo.
- No, I didn`t.
- I was trying the RetrofitFragment.
The interesting thing is that I unsubscribe on OnDestroy of that fragment. In the example the Observable was not unsubscribed, so, I created the local Subscriber, init it by button click, and unsubscribe on OnDestroy.
I have just pulled the changes and the issue still reproducing. I was debugging and the Observable is being unsubscribed.
Steps to reproduce:
- Turn off the internet (to simulate no internet connection exception)
- Open the Retrofit-RxJava example.
- Press the button.
- onError observer is called. Error logged.
- close the app with back button.
- do 2,3 steps
- two onError is called. 2 Error logged.
Kill the process - helps to fix the issue.
Looks like Observable holds the Activities reference, even app was closed with back button.
excellent catch! couple of points:
a. the "leak" was not being caused by any of the Rx activity. so the Retrofit + RxJava combination was not causing any of the issues. I tested this by removing all Rx related stuff from the fragment and placing a debug log statement in the onResume
method. You'll notice multiple instances of the fragment being created.
b. while i cannot pinpoint and tell you exactly what went wrong, i cleaned up the fragment construction and the backstack behavior. This solved the problem. If you have a look at #a0b2e2d you'll see the differences. Essentially i remove the useless activity_main layout, and when adding fragments i use android.R.id.content
instead of a custom id.
Needless to say, post cleanup, the multiple fragment instance logs didn't show up.
i'm going ahead and closing this issue. thanks for letting me know. if you're still facing issues, let me know and i'll reopen.
Yes, the issue is resolved.
Thanks for your contribution to RxJava tutorials! The examples are clear and useful! :)