question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

2.x: BoundedReplayBuffer temporarily leaks memory

See original GitHub issue

When using Observable.replay(N), the BoundedReplayBuffer keeps up to N+1 items in its buffer. When using replay(1) for example, it keeps a reference to the most recent item, but also the previous, stale item.

Take for example this trivial snippet of code that provides an available Android View as a stream:

val eventsSubject = BehaviorSubject.create<Event<View>>()
val view: Observable<Option<View>> = eventsSubject
    .map { event ->
        when(event) {
            is Attached<View> -> Option.just(event.view)
            is Detached -> Option.empty()
        }
    }
    .replay(1).refCount()

The replay(1) call suggests a single value is cached, but the implementation keeps a strong reference to the previous item as well. Since this happens as a hidden side effect and rather counter intuitively, it is easy to accidentally leak memory – even when the client code seems to be careful about it. Especially with Android Views referencing Activity contexts this is problematic.


https://github.com/ReactiveX/RxJava/pull/5282 proposed a fix for this at the cost of an extra Node allocation, which turned out to be unwanted. The proposed alternative there refers to RxJava2Extensions#cacheLast, but this only emits the very last item, not intermediates.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
akarnokdcommented, May 7, 2019

Item lifecycle is not part of the Reactive Streams model, thus the operator only guarantees one gets up to a number of items when subscribing to cold replay. People have been using LeakCanary to detect such cases and most likely reworked their flow to not use replay.

0reactions
akarnokdcommented, Jun 24, 2019

Closing via #6532 for 3.x.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Everything you need to know about Memory Leaks in Android.
Memory Leaks : Temporary vs Permanent. Leaks can be divided into two categories: those that occupy the memory unit until the application ...
Read more >
How To Fix Windows 10 Memory Leaks - Online Tech Tips
This should fix the memory leak issue in most cases, at least temporarily, until you can find a permanent fix. Open the Start...
Read more >
c++ - Can references cause memory leaks? - Stack Overflow
Show activity on this post. Short answer: no. Longer answer: In that case, the compiler will make sure, that the referenced temporary object ......
Read more >
4 Types of Memory Leaks in JavaScript and How to Get Rid Of ...
In particular, global variables used to temporarily store and process big amounts of information are of concern. If you must use a global ......
Read more >
Java Memory Leaks: Solutions, Tools, Tutorials & More - Stackify
2. Avoid memory leaks related to a WebApp classloader ... A large number of temporary objects will slow down performance.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found