Io.realm.exceptions.RealmError: Fatal error. Mmap () error: Not enough memory on line io_realm_internal_SharedGroup.cpp 115

I have a chat application with a history cache in the Realm database wrapped in RxJava statements. Everything works fine, but I sometimes catch this exception on a specific set of devices:

io.realm.exceptions.RealmError: Unrecoverable error. mmap() failed: Out of memory in io_realm_internal_SharedGroup.cpp line 115
   at io.realm.internal.SharedGroup.createNativeWithImplicitTransactions(SharedGroup.java)
   at io.realm.internal.SharedGroup.<init>(SharedGroup.java:60)
   at io.realm.Realm.<init>(Realm.java:209)
   at io.realm.Realm.createAndValidate(Realm.java:600)
   at io.realm.Realm.create(Realm.java:563)
   at io.realm.Realm.getInstance(Realm.java:410)
   at io.realm.Realm.getInstance(Realm.java:367)
   at io.realm.Realm.getInstance(Realm.java:348)
   at ru.ltst.happer.data.rx.OnSubscribeRealm.call(OnSubscribeRealm.java:28)
   at ru.ltst.happer.data.rx.OnSubscribeRealm.call(OnSubscribeRealm.java:13)
   at rx.Observable.unsafeSubscribe(Observable.java:7495)
   at rx.internal.operators.OperatorSubscribeOn$1$1.call(OperatorSubscribeOn.java:62)
   at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
   at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
   at java.util.concurrent.FutureTask.run(FutureTask.java:237)
   at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
   at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
   at java.lang.Thread.run(Thread.java:818)

      

My code where I am writing chat messages to the database:

public void addMessagesToDb(List<UIMessage> messages) {
    final ArrayList<UIMessage> receivedMessages = new ArrayList<>(messages);
    Observable.create(new OnSubscribeRealm<RealmMessage>(application, databaseName) {
        @Override
        public RealmMessage get(Realm realm) {
            for (UIMessage message : receivedMessages) {
                RealmMessage realmMessage = new RealmMessage();
                realmMessage.setTimeMillis(message.timeMillis());
                realmMessage.setText(message.text());
                realmMessage.setPhotoUrl(message.photoUrl());
                realmMessage.setFromOutside(message.fromOutside());
                RealmDialog.addMessage(realm, message.userId(), RealmMessage.put(realm, realmMessage));
            }
            return new RealmMessage();
        }
    }).compose(this.<RealmMessage>applySchedulers())
            .subscribe(new WeakSubscriberDecorator<>(new SimpleSubscriber<RealmMessage>()));

      

OnSubscribeRealm.java:

public abstract class OnSubscribeRealm<T extends RealmObject> implements Observable.OnSubscribe<T> {
    private Context context;
    private String fileName;

    public OnSubscribeRealm(Context context) {
        this(context, null);
    }

    public OnSubscribeRealm(Context context, String fileName) {
        this.context = context.getApplicationContext();
        this.fileName = fileName;
    }

    @Override
    public void call(final Subscriber<? super T> subscriber) {
        final Realm realm = Realm.getInstance(context);

        T object;
        try {
            realm.beginTransaction();
            object = get(realm);
            realm.commitTransaction();
        } catch (RuntimeException e) {
            realm.cancelTransaction();
            subscriber.onError(new RealmException("Error during transaction.", e));
            return;
        } catch (Error e) {
            realm.cancelTransaction();
            subscriber.onError(e);
            return;
        }
        if (object != null) {
            subscriber.onNext(object);
        }
        subscriber.onCompleted();

        try {
            realm.close();
        } catch (RealmException ex) {
            subscriber.onError(ex);
        }
    }

    public abstract T get(Realm realm);
}

      

RealmDialog.java

a static method that adds a message to history

public static RealmMessage addMessage(Realm realm, String userId, RealmMessage realmMessage) {
    RealmDialog realmDialog = findBy(realm, userId);
    if (realmDialog != null) {
        RealmMessage result = RealmMessage.put(realm, realmMessage);
        realmDialog.getMessages().add(result);
        return result;
    }
    return null;
}

      

I made all requests on a background thread and tried to close all instances Realm

after transactions were committed. This error most often occurs on Samsung G900H devices.

+3


source to share





All Articles