realm / realm-java

Realm is a mobile database: a replacement for SQLite & ORMs
http://realm.io
Apache License 2.0
11.45k stars 1.75k forks source link

mmap() failed: Out of memory #7663

Closed KimiChiu closed 1 year ago

KimiChiu commented 2 years ago

How frequently does the bug occur?

All the time

Description

I am trying to reproduce the 'realm file size too large' issues from my Android emulator. So I use these codes to fill the database.

 StringBuilder stringBuilder = new StringBuilder();

                        for(int i = 0; i< 500; i++) {
                            stringBuilder.append("新輸入密碼,重新連線時若密碼錯誤可以重新輸入密碼並更新資料庫");
                        }

                        String data = stringBuilder.toString();

                        int from = testIndex;
                        int to = testIndex + 100;
                        for(int i = from; i < to; i++) {
                            RealmSyncHelper.getInstance().getChatRoomService().insertWithCheck(i, 0, "id", "test", "test", 0, 0, data, data, "test", 0);
                            testIndex ++;
                        }

                        Timber.d("testIndex = " + testIndex);

After the file size increased to 300 MB it starts to throw this exception. And I can't write any data into database anymore.

Stacktrace & log output

java.lang.RuntimeException: mmap() failed: Out of memory size: 314572800 in /tmp/realm-java/realm/realm-library/src/main/cpp/io_realm_internal_OsSharedRealm.cpp line 107
        at io.realm.internal.OsSharedRealm.nativeGetSharedRealm(Native Method)
        at io.realm.internal.OsSharedRealm.<init>(OsSharedRealm.java:173)
        at io.realm.internal.OsSharedRealm.getInstance(OsSharedRealm.java:249)
        at io.realm.BaseRealm.<init>(BaseRealm.java:141)
        at io.realm.BaseRealm.<init>(BaseRealm.java:108)
        at io.realm.Realm.<init>(Realm.java:159)
        at io.realm.Realm.createInstance(Realm.java:495)
        at io.realm.RealmCache.createInstance(RealmCache.java:481)
        at io.realm.RealmCache.doCreateRealmOrGetFromCache(RealmCache.java:448)
        at io.realm.RealmCache.createRealmOrGetFromCache(RealmCache.java:412)
        at io.realm.Realm.getInstance(Realm.java:424)
        at com.kimieno.sync.domain.dao.realm.impl.RealmSyncHelper.realm(RealmSyncHelper.java:164)
        at com.kimieno.sync.domain.service.realm.impl.ChatUserService.insertWithCheck(ChatUserService.java:31)
        at com.kimieno.sync.domain.dao.realm.impl.RealmSyncHelper$3.run(RealmSyncHelper.java:267)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
2022-03-17 00:05:57.767 21112-21112/com.ihad.ptt E/App: Uncaught exception is:
    java.lang.RuntimeException: mmap() failed: Out of memory size: 314572800 in /tmp/realm-java/realm/realm-library/src/main/cpp/io_realm_internal_OsSharedRealm.cpp line 107
        at io.realm.internal.OsSharedRealm.nativeGetSharedRealm(Native Method)
        at io.realm.internal.OsSharedRealm.<init>(OsSharedRealm.java:173)
        at io.realm.internal.OsSharedRealm.getInstance(OsSharedRealm.java:249)
        at io.realm.BaseRealm.<init>(BaseRealm.java:141)
        at io.realm.BaseRealm.<init>(BaseRealm.java:108)
        at io.realm.Realm.<init>(Realm.java:159)
        at io.realm.Realm.createInstance(Realm.java:495)
        at io.realm.RealmCache.createInstance(RealmCache.java:481)
        at io.realm.RealmCache.doCreateRealmOrGetFromCache(RealmCache.java:448)
        at io.realm.RealmCache.createRealmOrGetFromCache(RealmCache.java:412)
        at io.realm.Realm.getInstance(Realm.java:424)
        at com.kimieno.sync.domain.dao.realm.impl.RealmSyncHelper.realm(RealmSyncHelper.java:164)
        at com.kimieno.sync.domain.service.realm.impl.ChatUserService.insertWithCheck(ChatUserService.java:31)
        at com.kimieno.sync.domain.dao.realm.impl.RealmSyncHelper$3.run(RealmSyncHelper.java:267)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

Can you reproduce the bug?

Yes, always

Reproduction Steps

Use the code above repeatedly until it throws exception.

Version

above 7.0.8

What SDK flavour are you using?

Local Database only

Are you using encryption?

Yes, using encryption

Platform OS and version(s)

Android API 29 emulator

Build environment

Android Studio version: 4.1.3 Android Build Tools version: 29.0.2 Gradle version: 6.5

clementetb commented 2 years ago

If the database file is growing too large is usually a Realm version pinning issue, a Realm instance is not closed properly, or it is instantiated in a non-looper thread.

We would need more info about what this line does as it does not show any of Realm logic: RealmSyncHelper.getInstance().getChatRoomService().insertWithCheck.

KimiChiu commented 2 years ago

If the database file is growing too large is usually a Realm version pinning issue, a Realm instance is not closed properly, or it is instantiated in a non-looper thread.

Yes, I knew it. I just want to make sure my app has an ability to recover from this situation. And this one is not what I was expected.

We would need more info about what this line does as it does not show any of Realm logic: RealmSyncHelper.getInstance().getChatRoomService().insertWithCheck.

It's a simple insert method. And these i, 0, "id", "test", "test", 0, 0, data, data, "test", 0 are values.

edualonso commented 1 year ago

We couldn't reproduce your issue. It would help us if you could provide a sample project that we could look at for debugging purposes.

rorbech commented 1 year ago

Closing the issue due to lack of feedback. As mentioned this is most likely because the realm lifecycle is not handled correctly and the realm is not closed after use. If you need more input please supply the source code for the insertWithCheck method, so that we have a chance to see what is going on.