Rxjava和Retrofit结合使用大量请求时候出现OOM的问题

在使用RxJava+Retrofit时遇到OOM问题,主要是由于线程池创建过多线程。解决方案一是使用Retrofit的createAsync()避免额外线程创建;二是自定义Scheduler限制线程数量。核心是限制RxJava的线程数量以防止内存溢出。
摘要由CSDN通过智能技术生成

在使用RxJava+Retrofit的过程中,出现了OOM的问题,报错日志如下:

java.lang.OutOfMemoryError: pthread_create (1040KB stack) failed: Try
again
at java.lang.Thread.nativeCreate(Native Method)
at java.lang.Thread.start(Thread.java:733)
at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:970)
at java.util.concurrent.ThreadPoolExecutor.ensurePrestart(ThreadPoolExecutor.java:1611)
at java.util.concurrent.ScheduledThreadPoolExecutor.delayedExecute(ScheduledThreadPoolExecutor.java:342)
at java.util.concurrent.ScheduledThreadPoolExecutor.schedule(ScheduledThreadPoolExecutor.java:579)
at java.util.concurrent.ScheduledThreadPoolExecutor.submit(ScheduledThreadPoolExecutor.java:680)
at io.reactivex.internal.schedulers.NewThreadWorker.scheduleActual(NewThreadWorker.java:145)
at io.reactivex.internal.schedulers.IoScheduler$EventLoopWorker.schedule(IoScheduler.java:239)
at io.reactivex.Scheduler.scheduleDirect(Scheduler.java:203)
at io.reactivex.Scheduler.scheduleDirect(Scheduler.java:179)
at io.reactivex.internal.operators.observable.ObservableSubscribeOn.subscribeActual(ObservableSubscribeOn.java:36)
at io.reactivex.Observable.subscribe(Observable.java:12267)
at io.reactivex.internal.operators.observable.ObservableMap.subscribeActual(ObservableMap.java:32)
at io.reactivex.Observable.subscribe(Observable.java:12267)
at io.reactivex.internal.operators.observable.ObservableObserveOn.subscribeActual(ObservableObserveOn.java:45)
at io.reactivex.Observable.subscribe(Observable.java:12267)

原因是在创建大量请求时候会创建大量的线程, 在手机上由于手机对进程有线程数量的限制导致了闪退.

第一种解决方案

可以查看:
https://github.com/ReactiveX/RxAndroid/issues/387

最佳答案是:

JakeWharton commented on 9 Aug 2017

The problem is that Schedulers.io() uses a cached thread pool without
a limit and thus is trying to create 1500 threads. You should consider
using a Scheduler that has a fixed limit of threads, or using RxJava
2.x’s parallel() operator to parallelize the operation to a fixed number of workers.

If you’re using raw Retrofit by default it uses OkHttp’s dispatcher
which limits the threads to something like 64 (with a max of 5 per
host). That’s why you aren’t seeing it fail.

If you use createAsync() when creating the RxJava2CallAdapterFactory
it will create fully-async Observable instances that don’t require a
subscribeOn and which use OkHttp’s Dispatcher just like Retrofit would
otherwise. Then you only need observeOn to move back to the main
thread, and you avoid all additional thread creation.

主要意思就是: 如果只使用retrofit是不会出现这个问题的, 由于rxjava自身没有对线程数量做限制所以可能会出现这个问题.

这个解决方法主要有两点:
首先是在创建retrofit的时候使用 createAsync()

if (retrofit == null) {
   
            retrofit = new Retrofit.Builder()
                    .baseUrl(baseurl)       //设置远程地址
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.createAsync())
                    .client(OkHttpHelper.getInstance().getOkHttpClient())
                    
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值