You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用RxJava+Retrofit实现HTTP轮询时出现java.lang.OutOfMemoryError问题

问题根因
  • 核心原因是使用无并发限制的flatMap操作符导致HTTP请求大量堆积:Observable.interval每隔500ms就会生成一个事件,flatMap会同时处理所有事件、并行发起网络请求,若网络环境差、单个请求响应时间超过500ms,请求就会持续累积。每个OkHttp请求都会占用线程、TCP连接等资源,累积到系统线程上限后就会抛出pthread_create相关的OOM异常。
  • 额外可能的诱因:OkHttp未配置全局连接池复用、请求未设置超时,导致无效请求长期占用资源。
解决方案

1. 替换操作符避免并行请求

优先用switchMap替代flatMap:每当新的轮询事件触发时,自动取消上一个未完成的旧请求,保证同一时间最多只有一个活跃的轮询请求,完全避免资源堆积。
如果需要保证每个请求都得到响应后再发起下一个,可以用concatMap,强制请求串行执行。

2. 限制flatMap并发数(不替换操作符的兼容方案)

如果需要保留flatMap的使用,给flatMap增加第二个参数设置最大并发数为1,强制串行执行:

.flatMap(new Func1<Long, Observable<?>>() {
    @Override
    public Observable<?> call(Long aLong) {
        return CimaComm.getInstance().getService().getPaymentStatus();
    }
}, 1) // 限制最大并发为1

3. 补充基础配置优化

  • 给OkHttp配置全局单例的连接池,复用TCP连接,减少线程创建开销
  • 给网络请求增加合理的超时时间(建议10s以内),避免无响应的请求长期占用资源
  • 补充线程调度指定:轮询属于IO操作,指定subscribeOn(Schedulers.io()),如果是安卓端最后回调到主线程的话补充observeOn(AndroidSchedulers.mainThread())
修正后的示例代码
Observable.interval(500, TimeUnit.MILLISECONDS)
        // 用switchMap自动取消旧请求,同一时间仅保留一个活跃请求
        .switchMap(new Func1<Long, Observable<?>>() {
            @Override
            public Observable<?> call(Long aLong) {
                return CimaComm.getInstance().getService().getPaymentStatus();
            }
        })
        .takeUntil(new Func1<Object, Boolean>() {
            @Override
            public Boolean call(Object o) {
                CimaPaymentStatusResponse responseState = (CimaPaymentStatusResponse) o;
                return responseState.status == CimaStatusEnum.completed || responseState.status == CimaStatusEnum.faulted;
            }
        })
        // 指定IO线程执行请求,安卓端可加.observeOn(AndroidSchedulers.mainThread())切回主线程
        .subscribeOn(Schedulers.io())
        .subscribe(this::onPaymentPollingUpdate, this::handleCimaError);

内容的提问来源于stack exchange,提问作者giordy16

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 19:36:00