Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.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 使用replay(selectorFoo)但不使用publish(selectorFoo)时的OOM_Java_Rx Java2_Project Reactor - Fatal编程技术网

Java 使用replay(selectorFoo)但不使用publish(selectorFoo)时的OOM

Java 使用replay(selectorFoo)但不使用publish(selectorFoo)时的OOM,java,rx-java2,project-reactor,Java,Rx Java2,Project Reactor,这与OOM冲突: Flowable.range(1, 5000) .map(__ -> new byte[1024 * 1024]) .replay( fb -> fb.take(1) .concatMap(__ -> fb) ,1 ) .count() .toFlowable() .bloc

这与OOM冲突:

Flowable.range(1, 5000)
        .map(__ -> new byte[1024 * 1024])
        .replay(
          fb ->
            fb.take(1)
              .concatMap(__ -> fb)
          ,1
        )
        .count()
        .toFlowable()
        .blockingSubscribe(c -> System.out.println("args = [" + c + "]"));
我认为这是因为
replay
保留了上游的排放量,即使我认为
1
缓冲区大小提示不会。。。。我错过了什么

这不会崩溃:

Flowable.range(1, 5000)
        .map(__ -> new byte[1024 * 1024])
        .publish(
          fb ->
            fb.take(1)
              .concatMap(first -> fb.startWith(first))
          ,1
        )
        .count()
        .toFlowable()
        .blockingSubscribe(c -> System.out.println("args = [" + c + "]"));

但我不确定我是否能保证从上游获得所有的排放量…

我已经对此进行了调查,并找到了问题的原因:RxJava 2中的
回放中有一个bug

发生的情况是,
replay
在局部变量中保存对2个订阅者的引用,一个用于
take
,另一个用于
concatMap
的内部使用者,因此从主线程到失效的
take
仍然引用第一个项目。由于有界重播使用了一个链表,因此第一个项目通过其“下一个”链接不断引用更新的项目,并最终耗尽内存


publish
不保留对旧值的引用,因此这不是问题。

感谢您查看此内容。在第二个示例中,使用
publish()
take(1)
获取其项目和
concatMap
订阅之间,是否可能丢失上游排放?我试图以各种方式打破它,但我似乎总是得到所有的排放,但rxJava2背后的策划人的确认会更令人信服:)。另外,我是否需要在github上为此提交问题?噢,天哪,我刚刚看到它已经被修复并合并到下一个版本:)。谢谢我将尝试回答关于
publish()
示例的问题。反应式规范说明不能同时调用
onNext()
。因此,只有在上一个
onNext()
完成时才能调用
onNext()
。由于
publish()
的内部流没有引入任何异步性,这意味着在
take(1)
上调用第一个
onNext()
,然后在
concatMap()
上调用
onNext()
,后者将调用其内部函数并订阅生成的
Flowable
。然后才允许调用下一个
onNext()
,因此在给定示例中不会丢失任何排放。