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

Fatal Exception: java.lang.RuntimeException when Realm.getDefaultInstance() is called #7735

Closed Oshuremy closed 1 year ago

Oshuremy commented 1 year ago

How frequently does the bug occur?

Sometimes

Description

I am receiving this crash on my production app, it rarely happens but when it does it's about 200 crashes each times.

Crashlytics gets those 3 Exception with the same stacktrace.

It's occur when Realm.getDefaultInstance() is called

Stacktrace & log output

Fatal Exception: java.lang.RuntimeException
Unable to instantiate activity ComponentInfo{com.xxx/com.xxx.ui.activity.main.LoggedActivity}: java.lang.RuntimeException: write() failed: No space left on device in /tmp/realm-java/realm/realm-library/src/main/cpp/io_realm_internal_OsSharedRealm.cpp line 107

Fatal Exception: java.lang.RuntimeException
mmap() failed: Out of memory size: 37748736 offset: 67108864 in /tmp/realm-java/realm/realm-library/src/main/cpp/io_realm_internal_OsSharedRealm.cpp line 107

Fatal Exception: java.lang.RuntimeException
Unable to create application com.xxx.App: io.realm.exceptions.RealmFileException: Directory at path '/data/user/0/com.xxx/files/xxx.realm' does not exist. (open("/data/user/0/com.xxx/files/xxx.realm") failed: No such file or directory Path: /data/user/0/com.xxx/files/xxx.realm Exception backtrace: <backtrace not supported on this platform>) (/data/user/0/com.xxx/files/xxx.realm) in /tmp/realm-java/realm/realm-library/src/main/cpp/io_realm_internal_OsSharedRealm.cpp line 107 Kind: NOT_FOUND.

io.realm.internal.OsSharedRealm.nativeGetSharedRealm (OsSharedRealm.java)
io.realm.internal.OsSharedRealm.<init> (OsSharedRealm.java:174)
io.realm.internal.OsSharedRealm.getInstance (OsSharedRealm.java:259)
io.realm.BaseRealm.<init> (BaseRealm.java:142)
io.realm.BaseRealm.<init> (BaseRealm.java:109)
io.realm.Realm.<init> (Realm.java:161)
io.realm.Realm.createInstance (Realm.java:535)
io.realm.RealmCache.createInstance (RealmCache.java:508)
io.realm.RealmCache.doCreateRealmOrGetFromCache (RealmCache.java:461)
io.realm.RealmCache.createRealmOrGetFromCache (RealmCache.java:422)
io.realm.Realm.getDefaultInstance (Realm.java:443)

Can you reproduce the bug?

Not yet

Reproduction Steps

No response

Version

10.11.1

What SDK flavour are you using?

Local Database only

Are you using encryption?

No, not using encryption

Platform OS and version(s)

Android

Build environment

Gradle version: 7.2.2

rorbech commented 1 year ago

@Oshuremy Sounds like your users are just running out of space and the problem will probably just continue to persist if the app is restarted. This doesn't necessarily need to be related to your app, but if you suspecting that it has something to do with your realm file, then you can read the documentation on how to improve that in https://www.mongodb.com/docs/realm/sdk/java/fundamentals/realms/#realm-file-size

Oshuremy commented 1 year ago

Is there a way to know more about thoses error ? It can be link to app update and migration process ?

We suffered a crash spike again yesterday

cmelchior commented 1 year ago

It depends on what you want to achieve? You can introspect the error we are throwing and if it reports "out of space" you can display a message to the user asking them to clean up?

github-actions[bot] commented 1 year ago

This issue has been automatically closed because there has been no response to our request for more information from the original author. With only the information that is currently in the issue, we don't have enough information to take action. Please reach out if you have or find the answers we need so that we can investigate further.

Oshuremy commented 1 year ago

Hi,

I have an unanswered question on github discution, it's pretty like to this subject. https://github.com/realm/realm-java/discussions/7764

Could you explain me please ?

cmelchior commented 1 year ago

compactOnLaunch operates on a copy of the file, and once the compaction is done, it will replace the original one. But this also means that while it is running it will require 2x the amount of space of the original file.

So if you are running into errors like No space left on device in /tmp/realm-java/realm/realm-library/src/main/cpp/io_realm_internal_OsSharedRealm.cpp line 107 using compact will not solve it. You will need to free up space in some other fashion.

I don't know if that answers your question?

Oshuremy commented 1 year ago

Thank you, It answers a part of my questions.

But I always have this question in mind (from https://github.com/realm/realm-java/discussions/7764) :

Generally it's better to have 1 realm instance for all and close when the app is close OR 1 realm instance each time we want to read/write on realm and close it immediatly ? (For me the second is better but in that case compactOnLaunch is called everytime.)

edualonso commented 1 year ago

Opening a realm every time you need one adds overhead since there are lots of things happening when you call getInstance, plus you have to remember to close it after every use, or else you will be leaking those instances which could result in out of memory errors.

However, having one singleton instance poses different challenges, especially in a multithreading scenario. For example, processing asynchronous callbacks on background threads and saving data into your realm. One has to be aware of which thread owns the singleton or else you might risk seeing thread violation errors. These can be solved using asynchronous transactions and asynchronous queries though, but that adds complexity to your solution.

As you can see there is not one better answer but rather depends on your architecture and your requirements.

Oshuremy commented 1 year ago

Thanks for this answer I'll work on that