产出的原因
当上下游在不同的线程中,通过Observable发射,处理,响应数据流时,如果上游发射数据的速度快于下游接收处理数据的速度,这样对于那些没来得及处理的数据就会造成积压,这些数据既不会丢失,也不会被垃圾回收机制回收,而是存放在一个异步缓存池中,如果缓存池中的数据一直得不到处理,越积越多,最后就会造成内存溢出,这便是响应式编程中的背压(backpressure)问题
解决思路
响应式拉取是观察者主动去被观察者那里拉取事件,而被观察者则是被动等待通知再发射事件。
背压策略
-
MISSING(MissingEmitter)
在此策略下,通过Create方法创建的Flowable相当于没有指定背压策略,不会对通过onNext发射的数据做缓存或丢弃处理,需要下游通过背压操作符
-
ERROR(ErrorAsyncEmitter)
在此策略下,如果放入Flowable的异步缓存池中的数据超限了,则会抛出MissingBackpressureException异常
-
BUFFER(BufferAsyncEmitter)
部维护了一个缓存池SpscLinkedArrayQueue,其大小不限,此策略下,如果Flowable默认的异步缓存池满了,会通过此缓存池暂存数据,它与Observable的异步缓存池一样,可以无限制向里添加数据,不会抛出MissingBackpressureException异常,但会导致OOM
-
DROP(DropAsyncEmitter)
在此策略下,如果Flowable的异步缓存池满了,会丢掉上游发送的数据
-
DROP(LatestAsyncEmitter)
与Drop策略一样,如果缓存池满了,会丢掉将要放入缓存池中的数据,不同的是,不管缓存池的状态如何,LATEST都会将最后一条数据强行放入缓存池中,来保证观察者在接收到完成通知之前,能够接收到Flowable最新发射的一条数据
Subscription
响应式拉取方式,来设置下游对数据的请求数量,上游可以根据下游的需求量,按需发送数据,如果不显示调用request()则默认下游的需求量为零,所以运行上面的代码后,上游Flowable发射的数据不会交给下游Subscriber处理。