Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在这种情况下,可观察对象会因为被垃圾收集而中途停止发射吗?_Java_Kotlin_Garbage Collection_Rx Java2 - Fatal编程技术网

Java 在这种情况下,可观察对象会因为被垃圾收集而中途停止发射吗?

Java 在这种情况下,可观察对象会因为被垃圾收集而中途停止发射吗?,java,kotlin,garbage-collection,rx-java2,Java,Kotlin,Garbage Collection,Rx Java2,我想知道在这种情况下,可观察对象是否有资格被垃圾收集: fun getObservable() = Observable.interval(500, TimeUnit.Milliseconds) fun main(args: Array<String>) { getObservable().subscribe { println(it) } //Just to be able to observe the output. Thread.sleep(20*1

我想知道在这种情况下,可观察对象是否有资格被垃圾收集:

fun getObservable() = Observable.interval(500, TimeUnit.Milliseconds)

fun main(args: Array<String>) {
    getObservable().subscribe { println(it) }

    //Just to be able to observe the output.
    Thread.sleep(20*1000)
}
MyViewModel.kt:

class MyViewModel(private val repository: Repository): ViewModel() {

    init {
        repository.getUserPrefs()
            .subscribe { //Code with UI state side effects }
    }
}

在我的应用程序中,Repository的实现将是一个单独的实现。对于那些不熟悉Android的人来说,只需知道ViewModel可以持续相当长的时间。它的工作基本上是负责管理UI状态。

因此,在
睡眠
退出并停止发射之后。如果您使用
Thread.sleep(1000)
尝试它,您将看到它只输出

0
1
原因是您的程序终止

您需要的可能是
阻止订阅

getObservable().blockingSubscribe { println(it) }
只有在
可观察的
完成后才会返回

请注意,您可以订阅3种类型的事件:
onNext
onError
onComplete

getObservable().blockingSubscribe({
    println(it)
}, {
    throw it
}, {
    println("finished")
})
订阅全部3个不会改变订阅服务器超出范围的事实,因此您仍然需要使用
blockingSubscribe
。如果要在线程之间卸载工作,可以使用
subscribeOn
observeOn

getObservable()
        .subscribeOn(Schedulers.computation())
        .observeOn(Schedulers.single())
        .blockingSubscribe {
            println(it)
        }
你可以阅读更多关于这些

关于垃圾收集

Java垃圾收集器足够智能,可以回收相互引用但未被所谓的“根引用”引用的资源:

那么,为什么您的
可观察的
在与其他对象分离的情况下仍保持运行?答案是Java中有多种类型的“根”引用:

  • 局部变量
  • 活动Java线程
  • 静态变量
  • JNI参考

在您的情况下,当您在
Observable
上调用
subscribe
时,它会将工作卸载到RxJava-s线程上,这些线程是“根”线程引用本身,因此即使您没有任何这些对象的引用,它们仍将无限期地运行,或者直到
线程终止。

我不知道具体的实现细节,但是为了让
可观察的
接收发射项,发射器需要保留对它的引用,因此,只要发射器没有被垃圾收集,可观察的
也不会被垃圾收集。@user2340612谢谢。现在有道理了。我会等待更多的答案只是为了确定。但是非常感谢你。BTW我主要使用C++直到6-8个月前。我对Java和Kotlin有点经验。我在这些方面很有成效,但偶尔,我会发现自己被这些事情难倒。我对GC没有很好的了解。你能推荐一些资料来帮助我更清楚地解释这件事吗?我读到了另一个对我来说非常有趣的“垃圾收集器会破坏这个程序吗”的问题……不,垃圾收集器在那里,这样程序员就可以不再担心内存,而不再担心垃圾收集器了。如果添加一个垃圾收集器,通过收集仍在使用的对象来破坏程序,那是毫无意义的。除非
subscribe
的文档明确表示要使用某种弱引用来允许对象被收集(这也没有多大意义,但有些API做了这种荒谬的事情)。@Holger我有这个疑问,因为正如我所提到的,我对垃圾收集语言相对较陌生。我知道理想的GC不应该妨碍程序员,但我不知道在现实生活中,这样的问题也不会发生。我只是想寻找可能出现问题的案例。为了安全起见。你的评论让我明白了这一点。谢谢你的帮助。谢谢你的回复。在我看来,调用
subscribe()
不会等待
Observable
使用的线程完成,而调用
blockingSubscribe()
会等待它。在我的情况下,
可观察的
将在我的应用程序中持续很长一段时间。问题不在于
可观察的
是否能够完成。这是在我的应用程序完成之前,它是否会被垃圾收集,而应用程序仍然依赖于它。因此,出于这个问题的目的,假设程序将运行很长一段时间(这样GC可能会运行)。它们如何依赖于您的
可观察的
?你能给我们看更多的代码吗?酷,现在我明白你的问题了。我修正了答案。谢谢!这个解释简直太棒了!!这使一切都非常清楚。我真的希望你有一个美好的一天。欢呼:)这句话“Java垃圾收集器足够智能,可以回收相互引用但不指向所谓“根引用”的资源”:“是错误的。要回收的资源指的是什么并不重要;重要的是他们是从哪里来的。保留从根引用传递引用的所有对象(=可从根访问)。
getObservable()
        .subscribeOn(Schedulers.computation())
        .observeOn(Schedulers.single())
        .blockingSubscribe {
            println(it)
        }
 (Root reference)

 (obj0) --> (obj1)
  \          /
   \        /
    \      /
    (obj2)

^^^--- obj0, 1 and 2 are eligible for garbage collection