Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does use of lambda in Android in Activity cause a memory leak?

I'm watching this presentation, and at 13:42 they say that using lambda in the way:

enter image description here

api.getEvents()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .doOnSubscribe(() -> loadingIndication.show())
    .doOnUnsubscribe(() -> loadingIndication.hide())
    .subscribe(...);

causes View to leak.

Can you explain how the leak works in this case? Does the leak appear depending on how we compile the code and what class we put the RxJava code (e.g. in Activity, in Application, in Service)?

like image 844
Marian Paździoch Avatar asked Jun 09 '17 09:06

Marian Paździoch


People also ask

What causes memory leaks in Android?

Memory leaks occur when an application allocates memory for an object, but then fails to release the memory when the object is no longer being used. Over time, leaked memory accumulates and results in poor app performance and even crashes.

Which function can be used to avoid a memory leak?

Make sure to call free() when you use malloc() or calloc() . Don't reassign pointer which points to allocated memory location without free() ing it first i.e. don't lose the reference.

Which of the following should be avoided to prevent memory leaks Android?

Option 1: As mentioned before never create a static variable of an inner class. Option 2: The class should be set to static. Instances of anonymous classes do not hold an implicit reference to their outer class when they are “static”. Option 3: Use a weakReference of any view/activity.


1 Answers

This causes a leak because lambdas are no different from anonymous inner classes where they will have an implicit reference to the current class where they're called, in this case it the Activity. So this piece of code actually has reference to your Activity.

api.getEvents()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .doOnSubscribe(() -> loadingIndication.show())
    .doOnUnsubscribe(() -> loadingIndication.hide())
    .subscribe(events -> {}, throwable -> {});

I haven't had the time to checkout the video but there is a way to handle this kind of possible memory leak by using CompositeDisposable and adding the Disposable returned from the above code through compositeDisposable.add() and calling compositeDisposable.clear() on your Activity's onDestroy().

like image 101
James Baltar Avatar answered Oct 16 '22 11:10

James Baltar