Schedulers.io创建了数百个RxCachedThreadSchedulers

时间:2015-07-08 13:37:39

标签: android multithreading rx-java rx-android

我在我的Android应用程序中使用RxJava,并且多次遇到OutOfMemoryError。我用设备管理器检查了它,我刚注意到,我有超过200个线程,大多数处于等待状态,通常是RxCachedThreadSchedulers。 OOMError因为有太多线程而被提出。 我还注意到,如果我按下一个按钮,它调用一个服务并获取一个令牌并缓存它,那么线程数会增加5倍!

所以,我用Google搜索并发现,Schedulers.io可以创建无限的线程。当我用Schedulers.computation替换每个Schedulers.io时,问题就消失了,但这没有任何意义,因为我使用Schedulers.io就像它应该被使用一样。

那么我如何使用Schedulers.io并确保它不会创建太多线程?

更新

我这样取消订阅:

    final Scheduler.Worker worker = Schedulers.io().createWorker();
    worker.schedule(new Action0() {
        @Override
        public void call() {
            long last = lastServerCommunication.getMillis();
            LongPreference pref = new LongPreference(mSharedPreferences, PREF_KEY_LAST_SERVER_COMMUNICATION);
            pref.set(last);
            worker.unsubscribe();
        }
    });

更新#2

我使用Schedulers.io的常规方式是:

public Observable<Scenario> load() {
    return Observable
            .create(new Observable.OnSubscribe<Scenario>() {
                @Override
                public void call(Subscriber<? super Scenario> subscriber) {
                    try {
                        Scenario scenario = mGson.fromJson(mSharedPreferences.getString("SCENARIO", null), Scenario.class);
                        subscriber.onNext(scenario);
                        subscriber.onCompleted();
                    } catch (Exception e) {
                        subscriber.onError(new Throwable());
                    }
                }
            })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread());
}

    mSomeSubscription = mSomeManager.readFromDatabase()
            .subscribeOn(Schedulers.io())
            .subscribe(new Observer<List<SomeEntry>>() {
                @Override
                public void onCompleted() { }

                @Override
                public void onError(Throwable e) {
                    // some logging
                }

                @Override
                public void onNext(List<SomeEntry> Entries) {
                    // Some action
                }
            });

3 个答案:

答案 0 :(得分:3)

好的,我找到了原因。请参阅说明更新#2

return Observable.create(new Observable.OnSubscribe<Something>() {
            @Override
            public void call(Subscriber<? super Something> subscriber) {
                try {
                  // Some action
                    subscriber.onNext(scenario);
                    subscriber.onCompleted();
                } catch (Exception e) {
                    subscriber.onError(new Throwable());
                }
            }
        })
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread());

当你创建像这样的冷Observable序列时,你必须确保你在订阅者上调用onCompleted,参见上面的subscriber.onCompleted();。 好吧,代码中的某些地方并没有,所以生成了线程。

非常感谢 akarnokd 寻求帮助!

答案 1 :(得分:2)

如果您使用Schedulers.io().createWorker(),一旦完成,您必须unsubscribe() Worker。常规的RxJava操作符不应泄漏任何工作者,因此也不应泄漏线程。

答案 2 :(得分:1)

太棒了,如果你不调用onComplete方法,那么线程(由Schedulers.io()创建)将保持等待并存在于那些冷可观察对象。