我正在尝试运行一个需要在我的数据库的每个文档上循环的脚本(使用NoSQL数据库)并复制每个文档“x time”。我知道因为数据库可能有很多文档,并且因为我们可以按照希望的时间复制它们,所以可以发生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 :(得分:0)
两件事:你的observable永远不会完成,你一次启动很多(订阅发生在不同的线程上)。
使用此:
Observable
.range(0, nbOccurrences)
.doOnNext(i -> duplicator.duplicatePatientsWithTheirMedicalRecords(patients, ToolsActivityViewModel.this))
.doOnNext(i -> informUserOnDuplicationProgress())
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.toBlocking()
.lastOrDefault(null);