Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ReplaySubject leaks subscribers even after unsubscribing? #939

Closed
mttkay opened this issue Mar 2, 2014 · 4 comments
Closed

ReplaySubject leaks subscribers even after unsubscribing? #939

mttkay opened this issue Mar 2, 2014 · 4 comments

Comments

@mttkay
Copy link
Contributor

mttkay commented Mar 2, 2014

On Android a common use case is to cache or replay an observable to UI components that might get temporarily destroyed due to e.g. screen rotations.

The biggest challenge on Android when using RxJava is therefore to make sure that no resource leaks occur; since subscribers, however, might be inner classes of an Android Activity or Fragment (if you're unfamiliar: think screen object), those will leak if strong references held within an operator are not released when unsubscribing from the sequence.

I just noticed that when using e.g. cache on a long running sequence, and subscribing and unsubscribing multiple times, the observer I subscribe to the sequence never seems to get finalized. Android's StrictMode indeed reports that the observer (and hence the entire screen) is being leaked:

E/StrictMode( 2791): class com.netflix.rxjava.android.samples.RetainedCacheFragmentActivity; instances=2; limit=1
E/StrictMode( 2791): android.os.StrictMode$InstanceCountViolation: class com.netflix.rxjava.android.samples.RetainedCacheFragmentActivity; instances=2; limit=1
E/StrictMode( 2791): class com.netflix.rxjava.android.samples.RetainedCacheFragmentActivity; instances=3; limit=1
E/StrictMode( 2791): android.os.StrictMode$InstanceCountViolation: class com.netflix.rxjava.android.samples.RetainedCacheFragmentActivity; instances=3; limit=1
E/StrictMode( 2791): class com.netflix.rxjava.android.samples.RetainedCacheFragmentActivity; instances=4; limit=1
E/StrictMode( 2791): android.os.StrictMode$InstanceCountViolation: class com.netflix.rxjava.android.samples.RetainedCacheFragmentActivity; instances=4; limit=1
E/StrictMode( 2791): class com.netflix.rxjava.android.samples.RetainedCacheFragmentActivity; instances=5; limit=1
E/StrictMode( 2791): android.os.StrictMode$InstanceCountViolation: class com.netflix.rxjava.android.samples.RetainedCacheFragmentActivity; instances=5; limit=1
E/StrictMode( 2791): class com.netflix.rxjava.android.samples.RetainedCacheFragmentActivity; instances=6; limit=1
E/StrictMode( 2791): android.os.StrictMode$InstanceCountViolation: class com.netflix.rxjava.android.samples.RetainedCacheFragmentActivity; instances=6; limit=1

I quickly glanced over the ReplaySubject subscription handling code, and it looks as if on unsubscribe, it removes the observer from the internal map; maybe that's broken, however?

@devisnik
Copy link
Contributor

We're observing the leakage on replaying as well (using version 0.17.0-RC7).

It seems that ReplaySubject uses some replayState map within its ReplayState that keeps references to the subscribers.

We currently work around the issue by avoiding (non-static) inner classes as subscribers and voiding references to activity/fragment-bound variables explicitly in onComplete. This of course only minimizes the impact of the leakage.

Any better suggestions of how to handle that?

@akarnokd
Copy link
Member

akarnokd commented May 8, 2014

I think this issue and some related problems with ReplaySubject are now fixed. Could you confirm & close this issue?

@mttkay
Copy link
Contributor Author

mttkay commented May 9, 2014

I can confirm this is fixed for us.

@benjchristensen
Copy link
Member

Thanks @mttkay for the confirmation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants