Skip to content

Commit 7ec5344

Browse files
committed
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.
1 parent f07765e commit 7ec5344

File tree

3 files changed

+494
-207
lines changed

3 files changed

+494
-207
lines changed

0 commit comments

Comments
 (0)