2017-08-08 11 views
5

मैं RxAndroid और RxJava का उपयोग करने के लिए नया हूं। मैं जीईटी अनुरोध करने के लिए आरएक्सजेवा + रेट्रोफिट 2 का उपयोग कर रहा हूं। मैं निम्नलिखित कोड का उपयोग करके लगभग 1500 जीईटी अनुरोध कर रहा हूं और स्मृति त्रुटि से बाहर हो रहा हूं। हालांकि इस बार एक ही कोड केवल retrofit, NO RxAndroid के साथ और यह काम करता है। तो मेरा निष्कर्ष यह था कि मैं RxAndroid में कुछ गलत कर रहा हूं। क्या आप कृपया जो खो रहे हैं उसके साथ मदद कर सकते हैं?मेमोरी त्रुटि से बाहर RxAndroid + RxJava + Retrofit2

कोड नमूना:

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; 
} 

त्रुटि:

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 
+0

लग रहा है कुछ लीक कर रहा है की तरह फ़ाइल संभालता है: 'AppData :: पाइप बनाने (2) में विफल रहा है: बहुत सारे खुले files'। कृपया सुनिश्चित करें कि यदि आप नेटवर्क डेटा के जवाब में नेटवर्क हैंडल (संभावना नहीं) लीक करते हैं और अन्यथा जांच करते हैं कि आपके पास नेटवर्क डेटा के जवाब में अनलोज़ फ़ाइल एक्सेस (जैसे डिस्क पर डेटा सहेजना) है तो नवीनतम रेट्रोफिट का उपयोग कर रहे हैं। – akarnokd

उत्तर

0

जोड़े अपने सभी Disposables करने के लिए CompositeDisposable और dispose यह हर चक्र के लिए

CompositeDisposable disposable = new CompositeDisposable(); 
mStoryListEmitter.subscribe(new Observer<List<Integer>>() { 
    @Override 
    public void onSubscribe(Disposable d) { 
     disposable.add(d); // adding disposable    
    } 

    @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() { 
     diposable.dispose(); // <--- Disposing on complete 
    } 
}) 

;

+0

मैंने आपके कोड नमूने की कोशिश की और मुझे अभी भी आउट ऑफ़ मेमोरी त्रुटि का सामना करना पड़ रहा है। –

4

RxAndroid github पर एक ही प्रश्न पोस्ट किया गया।

और JakeWharton जबाब acually heped

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.

+0

HI अनिल, मुझे भी एक ही समस्या है, क्या आप कृपया मेरी मदद कर सकते हैं कि आपने कैसे बनाया है Asyc() –

संबंधित मुद्दे