Uploaded image for project: 'Realm Java SDK'
  1. Realm Java SDK
  2. RJAVA-435

Out of memory: Be able to open large files.

      Goal

      Store 1000 records, each containing two short strings and 1MB byte array.

      Actual Results

      It seems (from the stack trace below) that it tries to allocate enormous RAM, which is strange to me...

      io.realm.exceptions.RealmError: Unrecoverable error. mmap() failed: Out of memory size: 1207959552 offset: 0 in /Users/kk/Desktop/MbiPersisterStudy/RealmBuild/realm-java/realm/realm-library/src/main/cpp/io_realm_internal_OsSharedRealm.cpp line 101
      at io.realm.internal.OsSharedRealm.nativeGetSharedRealm(Native Method)
      at io.realm.internal.OsSharedRealm.<init>(OsSharedRealm.java:171)
      at io.realm.internal.OsSharedRealm.getInstance(OsSharedRealm.java:241)
      at io.realm.internal.OsSharedRealm.getInstance(OsSharedRealm.java:231)
      at io.realm.RealmCache.doCreateRealmOrGetFromCache(RealmCache.java:332)
      at io.realm.RealmCache.createRealmOrGetFromCache(RealmCache.java:285)
      at io.realm.Realm.getDefaultInstance(Realm.java:407)
      at com.thales.gp.mbi.poc.kk.realm.module.b.MbiRealmCitizenTestInteractor.<init>(MbiRealmCitizenTestInteractor.java:47)
      at com.thales.gp.mbi.poc.kk.realm.module.b.MbiRealmCitizenTestInteractor.lambda$interaction$0(MbiRealmCitizenTestInteractor.java:23)
      at com.thales.gp.mbi.poc.kk.realm.module.b.-$$Lambda$MbiRealmCitizenTestInteractor$UH_qpTiiS6A-PYDCqBxF2bQysWY.subscribe(lambda)
      at io.reactivex.internal.operators.completable.CompletableCreate.subscribeActual(CompletableCreate.java:39)
      at io.reactivex.Completable.subscribe(Completable.java:2302)
      at io.reactivex.internal.operators.completable.CompletableSubscribeOn$SubscribeOnObserver.run(CompletableSubscribeOn.java:64)
      at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:38)
      at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:26)
      at java.util.concurrent.FutureTask.run(FutureTask.java:237)
      at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272)
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
      at java.lang.Thread.run(Thread.java:761)

      Steps & Code to Reproduce

      Please see the Goal section above. It is a benchmark to consider whether Realm is suitable for us or not: Therefore I can provide the whole Android project for it...

      The fragment of code which creates and verifies the data is hereafter - I HOPE I am doing something wrong:

      private static final int HUGE_DATA_RECORDS_COUNT = 500;
      private static final int HUGE_BINARY_DATA_SIZE = 1000000;
      
      private void createRecordWithHugeBinaryData(final @NonNull Realm realm) {
          Log.e(Tag.TAG, "Creating records with huge binary data...");
          final ElapsedTime measure = ElapsedTime.start();
          for (int index = 0; index < HUGE_DATA_RECORDS_COUNT; index++) {
              final MbiRealmEntityUser user = new MbiRealmEntityUser();
              final MbiRealmEntityUserI userI = user;
              final byte[] customData = new byte[HUGE_BINARY_DATA_SIZE];
              customData[0] = (byte) (0xFF & index);
              userI.setUserName("UN" + index);
              userI.setPassWord("PW" + index);
              userI.setCustomData(customData);
              realm.beginTransaction();
              realm.insertOrUpdate(user);
              realm.commitTransaction();
          }
          Log.e(Tag.TAG, measure.getMessage("Creating records with huge binary data: Consumed: %s"));
      }
      
      private void verifyRecordWithHugeBinaryData(final @NonNull Realm realm) {
          Log.e(Tag.TAG, "Verifying records with huge binary data...");
      
          final ElapsedTime measureTotal = ElapsedTime.start();
          final ElapsedTime measureFindAll = ElapsedTime.start();
          final RealmResults<MbiRealmEntityUser> users = realm.where(MbiRealmEntityUser.class).findAll();
          if (users.size() != HUGE_DATA_RECORDS_COUNT) {
              throw new IllegalStateException();
          }
          Log.e(Tag.TAG, measureFindAll.getMessage("Verifying records with huge binary data: Consumed: Find All: %s"));
      
          final ElapsedTime measureLoop1 = ElapsedTime.start();
          for (int index = 0; index < HUGE_DATA_RECORDS_COUNT; index++) {
              final MbiRealmEntityUserI user = users.get(index);
              if (user == null) {
                  throw new IllegalStateException();
              }
              if (!("UN" + index).equals(user.getUserName())) {
                  throw new IllegalStateException();
              }
              if (!("PW" + index).equals(user.getPassWord())) {
                  throw new IllegalStateException();
              }
          }
          Log.e(Tag.TAG,
                "Verifying records with huge binary data: Consumed: Per Record: Without Huge Data: " + (measureLoop1.getElapsed() / HUGE_DATA_RECORDS_COUNT)
                + " milliseconds");
      
          final ElapsedTime measureLoop2 = ElapsedTime.start();
          for (int index = 0; index < HUGE_DATA_RECORDS_COUNT; index++) {
              final MbiRealmEntityUserI user = users.get(index);
              if (user == null) {
                  throw new IllegalStateException();
              }
              final byte[] customData = user.getCustomData();
              if (customData == null) {
                  throw new IllegalStateException();
              }
              if (customData.length != HUGE_BINARY_DATA_SIZE) {
                  throw new IllegalStateException();
              }
              if (customData[0] != ((byte) (index & 0xFF))) {
                  throw new IllegalStateException();
              }
          }
          Log.e(Tag.TAG,
                "Verifying records with huge binary data: Consumed: Per Record: With Huge Data: " + (measureLoop2.getElapsed() / HUGE_DATA_RECORDS_COUNT)
                + " milliseconds");
      
          Log.e(Tag.TAG, measureTotal.getMessage("Verifying records with huge binary data: Consumed: Total: %s"));
      }
      

      Version of Realm and tooling

      Realm version(s): 6.0.1

      Realm Sync feature enabled: No

      Android Studio version: 3.5.2

      Android Build Tools version: com.android.tools.build:gradle:3.5.2

      Gradle version: ?

      Which Android version and device(s):

      • Android version 7.1.1
      • RAM: 2GB
      • The device is proprietary and special purpose (called Credence Two)

            Assignee:
            Unassigned Unassigned
            Reporter:
            unitosyncbot Unito Sync Bot
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: