question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Out of Memory Error RxAndroid + RxJava + Retrofit2

See original GitHub issue

I am new to using RxAndroid and RxJava. I am using RxJava + Retrofit2 to make GET requests. I am doing approximately 1500 GET requests using the following code and getting Out of memory error. However the same code this time with only retrofit, NO RxAndroid and it works. So my conclusion was I am doing something wrong in RxAndroid.

Code Sample:

Subject<Story> mStoryEmitter = PublishSubject.create();
private void getStory(int storyID) {
    HNApi.Factory.getInstance().getStory(storyID).subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(getStoryObserver());
}

mStoryListEmitter.subscribe(new Observer<List<Integer>>() {
    @Override
    public void onSubscribe(Disposable d) {}

    @Override
    public void onNext(List<Integer> value) {
        if(mRecyclerView != null) {
            mRecyclerView.setAdapter(null);
            if(mAdapter != null) {
                mAdapter.clear();
                mAdapter = null```
;
            }
        }
        mAdapter = new SimpleRecyclerViewAdapter();
        mRecyclerView.setAdapter(mAdapter);

        for(Integer storyID : value) {
            getStory(storyID);
        }
    }

    @Override
    public void onError(Throwable e) {}

    @Override
    public void onComplete() {}
});

private DisposableObserver<Story> getStoryObserver() {
    DisposableObserver<Story> observer = new DisposableObserver<Story>() {
        @Override
        public void onNext(Story value) {
            mStoryEmitter.onNext(value);
            dispose();
        }

        @Override
        public void onError(Throwable e) {

        }

        @Override
        public void onComplete() {

        }
    };
    return observer;
}

Error: Throwing OutOfMemoryError “Could not allocate JNI Env” java.lang.IllegalStateException: Fatal Exception thrown on Scheduler. at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:111) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) Caused by: java.lang.OutOfMemoryError: Could not allocate JNI Env at java.lang.Thread.nativeCreate(Native Method) at java.lang.Thread.start(Thread.java:1063) at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:921) at java.util.concurrent.ThreadPoolExecutor.ensurePrestart(ThreadPoolExecutor.java:1556) at java.util.concurrent.ScheduledThreadPoolExecutor.delayedExecute(ScheduledThreadPoolExecutor.java:310) at java.util.concurrent.ScheduledThreadPoolExecutor.schedule(ScheduledThreadPoolExecutor.java:543) at java.util.concurrent.ScheduledThreadPoolExecutor.submit(ScheduledThreadPoolExecutor.java:642) at io.reactivex.internal.schedulers.NewThreadWorker.scheduleActual(NewThreadWorker.java:120) at io.reactivex.internal.schedulers.IoScheduler$EventLoopWorker.schedule(IoScheduler.java:221) at io.reactivex.Scheduler.scheduleDirect(Scheduler.java:130) at io.reactivex.Scheduler.scheduleDirect(Scheduler.java:109) AppData::create pipe(2) failed: Too many open files at io.reactivex.internal.operators.observable.ObservableSubscribeOn.subscribeActual(ObservableSubscribeOn.java:36) at io.reactivex.Observable.subscribe(Observable.java:10514) at io.reactivex.internal.operators.observable.ObservableObserveOn.subscribeActual(ObservableObserveOn.java:44) at io.reactivex.Observable.subscribe(Observable.java:10514) at com.example.MainActivity.getStory(MainActivity.java:100) at com.example.MainActivity.access$300(MainActivity.java:25) at com.example.MainActivity$2.onNext(MainActivity.java:67) at com.example.MainActivity$2.onNext(MainActivity.java:49) at io.reactivex.subjects.PublishSubject$PublishDisposable.onNext(PublishSubject.java:263) at io.reactivex.subjects.PublishSubject.onNext(PublishSubject.java:182) at com.example.MainActivity$5.onNext(MainActivity.java:147) at com.example.MainActivity$5.onNext(MainActivity.java:138) at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.drainNormal(ObservableObserveOn.java:198) at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.run(ObservableObserveOn.java:250) at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:109) … 7 more AppData::create pipe(2) failed: Too many open files FATAL EXCEPTION: main Process: com.example, PID: 15857 java.lang.IllegalStateException: Fatal Exception thrown on Scheduler. at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:111) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) Caused by: java.lang.OutOfMemoryError: Could not allocate JNI Env at java.lang.Thread.nativeCreate(Native Method) at java.lang.Thread.start(Thread.java:1063) at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:921) at java.util.concurrent.ThreadPoolExecutor.ensurePrestart(ThreadPoolExecutor.java:1556) at java.util.concurrent.ScheduledThreadPoolExecutor.delayedExecute(ScheduledThreadPoolExecutor.java:310) at java.util.concurrent.ScheduledThreadPoolExecutor.schedule(ScheduledThreadPoolExecutor.java:543) at java.util.concurrent.ScheduledThreadPoolExecutor.submit(ScheduledThreadPoolExecutor.java:642) at io.reactivex.internal.schedulers.NewThreadWorker.scheduleActual(NewThreadWorker.java:120) at io.reactivex.internal.schedulers.IoScheduler$EventLoopWorker.schedule(IoScheduler.java:221) at io.reactivex.Scheduler.scheduleDirect(Scheduler.java:130) at io.reactivex.Scheduler.scheduleDirect(Scheduler.java:109) at io.reactivex.internal.operators.observable.ObservableSubscribeOn.subscribeActual(ObservableSubscribeOn.java:36) at io.reactivex.Observable.subscribe(Observable.java:10514) at io.reactivex.internal.operators.observable.ObservableObserveOn.subscribeActual(ObservableObserveOn.java:44) at io.reactivex.Observable.subscribe(Observable.java:10514) at com.example.MainActivity.getStory(MainActivity.java:100) at com.example.MainActivity.access$300(MainActivity.java:25) at com.example.MainActivity$2.onNext(MainActivity.java:67) at com.example.MainActivity$2.onNext(MainActivity.java:49) at io.reactivex.subjects.PublishSubject$PublishDisposable.onNext(PublishSubject.java:263) at io.reactivex.subjects.PublishSubject.onNext(PublishSubject.java:182) at com.example.MainActivity$5.onNext(MainActivity.java:147) at com.example.MainActivity$5.onNext(MainActivity.java:138) at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.drainNormal(ObservableObserveOn.java:198) at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.run(ObservableObserveOn.java:250) at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:109) … 7 more

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:1
  • Comments:8 (3 by maintainers)

github_iconTop GitHub Comments

23reactions
JakeWhartoncommented, Aug 9, 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.

0reactions
ouyangpengcommented, Mar 16, 2019
Read more comments on GitHub >

github_iconTop Results From Across the Web

Out of Memory Error RxAndroid + RxJava + Retrofit2
The problem is that Schedulers.io() uses a cached thread pool without a limit and thus is trying to create 1500 threads. You should...
Read more >
How to leak memory with Disposables in RxJava2 - Medium
Learn how memory leaks may happen while using RxJava 2 by storing Disposables and not handling them in a correct way.
Read more >
Introduction to RxJava for Android | Toptal
RxJava is a Java library that enables Functional Reactive Programming in Android ... Using this approach, we solve the problem (of potential memory...
Read more >
Android RxJava and Retrofit - DigitalOcean
RxAndroid is an extension of RxJava and it contains the Android threads to be used in the Android Environment.
Read more >
Android Development: 15 Libraries You Should Be Using
Images are the greatest source of Out of Memory errors in Android development. ... implementation 'com.squareup.retrofit2:retrofit:2.3.0'.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found