2017-06-16 111 views
0

我试图运行一个脚本,需要在我的数据库的每个文件(使用NoSQL数据库)上循环,并复制每个文件“X时间”。我知道,因为数据库可能有很多文档,并且我们可以按照希望的时间复制它们,所以OOM可能会发生。我试图避免它,但它仍然发生。有人可以帮助我吗?这里是我的代码:避免与分页的OOM异常

private void duplicates(int xFirsts, Integer nbOccurrences, DatabaseDuplicator duplicator) { 
    if(duplicateAllPatient.get()) 
     totalPatientsToDuplicate = couchbase.patientManager().count(false, false, null); 
    else 
     totalPatientsToDuplicate = xFirsts; 

    //Limit is to avoid to get an OOM error by getting too much patients from the database. 
    int limit = 500; 
    int skip = 0; 

    List<Patient> patients = couchbase.patientManager().findAll(limit, skip); 

    while (patients != null && !patients.isEmpty() && nbPatientsDuplicated < totalPatientsToDuplicate) { 
     startDuplication(nbOccurrences, duplicator, patients); 
     skip += limit; 
     if((skip + limit) > totalPatientsToDuplicate) 
      limit = totalPatientsToDuplicate - skip; 
     patients = couchbase.patientManager().findAll(limit, skip); 
    } 
} 

private void startDuplication(final Integer nbOccurrences, final DatabaseDuplicator duplicator, final List<Patient> patients) { 
    loadingInformation.set(""); 
    Observable<Integer> observable = Observable.create(new Observable.OnSubscribe<Integer>() { 
     @Override 
     public void call(Subscriber<? super Integer> subscriber){ 
      for (int i = 0; i < nbOccurrences; i++){ 
       duplicator.duplicatePatientsWithTheirMedicalRecords(patients, ToolsActivityViewModel.this); 
       subscriber.onNext(i); 
      } 
     } 
    }); 
    observable.subscribeOn(Schedulers.newThread()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(new Observer<Integer>() { 
       @Override 
       public void onCompleted() { 

       } 

       @Override 
       public void onError(Throwable e) { 
        e.printStackTrace(); 
       } 

       @Override 
       public void onNext(Integer integer) { 
        informUserOnDuplicationProgress(); 
       } 
      }); 
} 
+0

我假设,因为你从来没有观察到调用'onCompleted()'所以它永远不会死?你永远不会退订吗? – EpicPandaForce

回答

0

两件事情:你观察到的永远不会完成,并且开始许多人在一次(订阅发生在不同的线程)。

使用此:

Observable 
    .range(0, nbOccurrences) 
    .doOnNext(i -> duplicator.duplicatePatientsWithTheirMedicalRecords(patients, ToolsActivityViewModel.this)) 
    .doOnNext(i -> informUserOnDuplicationProgress()) 
    .subscribeOn(Schedulers.newThread()) 
    .observeOn(AndroidSchedulers.mainThread()) 
    .toBlocking() 
    .lastOrDefault(null); 
+0

我仍然在使用它的某个点上得到了OOM。这发生在> 3500的情况下,也许这是正常的?如果不是,我假设他们是'duplicatePatientsWithTheirMedicalRecords'内的另一个内存泄漏。 – MHogge

+0

我使用'new Action1(){...}'而不是Lambda表达式,是否会产生影响? (Java 8未在此项目中设置) – MHogge