Commit 30b1c80
authored
Fix ObservableCache GC issue (#7911)
* Fix ObservableCache GC issue
`ObservableCache` retains strong references to every event issued by its upstream source via its `head` field. These references remain reachable for the entire duration of the subscription, even if application code does not retain its own reference to the `ObservableCache` instance. This occurs because `ObservableCache` is currently the object that `implements Observer<T>` and is subscribed to the upstream `source`, which means that the source _must_ retain a reference to the `ObservableCache` until the subscription is either disposed of or reaches a terminal state. As a result, every cached `T` value remains reachable for the duration of the subscription to `source`, even if the application no longer retains the ability to issue new subscriptions to the `ObservableCache` instance.
This change fixes this issue by:
1. Splitting the `Observable` and `Observer` surfaces of `ObservableCache` into two distinct objects (`ObservableCache` which extends `Observable`, and `ObservableCache.Multicaster` which implements `Observer`)
2. Having only `ObservableCache` retain a reference to the `head`
3. Having only `ObservableCache.Multicaster` retain a reference to the current `tail`
4. Setting `Multicaster.tail` to `null` upon receipt of the upstream's terminal event
With this change, when `ObservableCache` goes out of scope, the only remaining references to the nodes of the linked list are `Multicaster.tail` and `CacheDisposable.node`. As subscribed `CacheDisposable` instances advance through the linked list, its nodes progressively become reclaimable, and eventually become fully reclaimable once the terminal event has been issued to all subscribers.
* Rewrite unit test to simply inflate heap
* Clean up imports
* Inline AtomicReference, delete unused class1 parent f07765e commit 30b1c80
File tree
2 files changed
+277
-207
lines changed- src
- main/java/io/reactivex/rxjava3/internal/operators/observable
- test/java/io/reactivex/rxjava3/internal/operators/observable
2 files changed
+277
-207
lines changed
0 commit comments