If I drop all explicit references to an observable I've subscribed to, will it be garbage collected?

I have an observable that emits a response from a remote server. I subscribe to it with an action that will stuff the result in a cache.

Bonus: Here's a clojure experiment demonstrating an observable being held onto while there's a subscriber, or maybe it's just showing a side-effect of ever subscribing to an observable.

(ns adhoc.rx-gc
  "Testing behavior of RxJava and garbage collection."
  (:require [rx.lang.clojure.core :as rx])
  (:import (java.lang.ref WeakReference)
           (java.util.concurrent TimeUnit)
           (rx Observable)))

(defn test-gc
  [sub?]
  ;; Hold source in an atom to be sure we can wipe references to it
  ;; and not worry about lexical scope.
  (let [a-src (atom (.delay (rx/return "hello") 5 TimeUnit/SECONDS))
        w-src (WeakReference. @a-src)]
    (when sub?
      (rx/subscribe @a-src
                    #(do (println "Value:" %)
                         (println "On-update ref:" (.get w-src)))))
    (reset! a-src nil)
    (System/gc)
    (println "After-gc ref:" (.get w-src))))

(comment
  (test-gc false)
  ;; After-gc ref: nil

  (test-gc true)
  ;; After-gc ref: #<Observable rx.Observable@21863f3b>
  ;; Value: hello
  ;; On-update ref: #<Observable rx.Observable@21863f3b>
)

Upvotes: 5

Views: 578

Answers (1)

zsxwing
zsxwing

Reputation: 20826

Once all of my own explicit references to the original observable are gone, is there danger that the side-effecting action mentioned above will fail to act?

It depends. If you use Scheduler, there may be some implicit references to your Observable in some thread of Scheduler.

More generally, what do I need to know as an rxjava user about garbage collection and rxjava?

Make sure you call Subsscription.unsubscribe when you want to release resources and never ignore Subscriptions returned by Observable.subscribe.

Upvotes: 1

Related Questions