17

I have a realm object with ~30 fields, after adding and removing several objects it seems that realm takes up quite a bit amount of space. The size of the allocated space seems to grow somewhat exponentially:

10*(add 100 + remove all) = 4 mb Data

15*(add 100 + remove all) = 33 mb Data

20*(add 100 + remove all) = 91 mb Data

25*(add 100 + remove all) = 179 mb Data

image

The file itself in data\data\app_folder\files\default.realm is 200 mb at this point.

Now this serious issue might be because i am not doing something properly. Before every insertion i do

Realm realm = Realm.getInstance(context);

realm.beginTransaction();
realm.where(RealmSubmission.class).findAll().clear();
// if i use realm.allObjects(RealmSubmission.class).clear(); the leak is even bigger, i get to 170mb Data with 20*(add 100 + remove all) even though both calls do the same by looking at their semantics.
realm.commitTransaction();

Adding items into realm looks like this:

    for (Submission submission : submissionList){
        realm.beginTransaction();

        RealmSubmission realmSubmission = realm.createObject(RealmSubmission.class);
        RealmObjectUtils.copySubmission(realmSubmission, submission);

        realm.commitTransaction();
    }

Any ideas?

4

5 回答 5

18

我做了一个简单的方法来在发生迁移异常时删除领域数据库文件(用于开发)。它还返回一个新的领域实例以防止出现任何问题。

public Realm buildDatabase(){
    RealmConfiguration realmConfiguration = new RealmConfiguration.Builder(this).build();

    try {
        return Realm.getInstance(realmConfiguration);
    } catch (RealmMigrationNeededException e){
        try {
            Realm.deleteRealm(realmConfiguration);
            //Realm file has been deleted.
            return Realm.getInstance(realmConfiguration);
        } catch (Exception ex){
            throw ex;
            //No Realm file to remove.
        }
    }
}
于 2015-07-18T23:26:52.017 回答
8

我尝试使用一个小型模型类(一个字符串,一个整数)进行复制,但没有成功。

您在模型中使用链接和/或链接列表吗?我可以看看吗?

一个原因可能是您有一个具有 RealmListdogs 字段的 Person 类。当您删除 Person 类型的所有元素时,Dogs 现在保留在数据库中。

编辑:在您提供数据后,我尝试了一些虚拟数据:

Realm.deleteRealmFile(this);
Realm realm = Realm.getInstance(this);
File realmFile = new File(this.getFilesDir(), "default.realm");

long tic = System.currentTimeMillis();
for (int i = 0; i < 25; i++) {
    for (int j = 0; j < 100; j++) {
        realm.beginTransaction();
        TestObject testObject = realm.createObject(TestObject.class);
        testObject.setApprovedBy("Approver_" + j);
        testObject.setAuthor("Author_" + j);
        testObject.setBannedBy("Banner_" + j);
        testObject.setClicked(j % 2 == 0);
        testObject.setCommentCount(j);
        testObject.setCreated(System.currentTimeMillis());
        testObject.setCreatedUTC(j*7);
        testObject.setEdited(j % 3 == 0);
        realm.commitTransaction();
    }
    realm.beginTransaction();
    realm.where(TestObject.class).findAll().clear();
    realm.commitTransaction();
    Log.i(TAG, "Size: " + realmFile.length());
}
long toc = System.currentTimeMillis();
Log.i(TAG, "Time: " + (toc - tic));

但我仍然无法重现:

10-08 14:39:01.579  29233-29233/myapp.realm.io.sizeleak I/REALMTEST﹕ Size: 24576
10-08 14:39:01.999  29233-29233/myapp.realm.io.sizeleak I/REALMTEST﹕ Size: 24576
10-08 14:39:02.409  29233-29233/myapp.realm.io.sizeleak I/REALMTEST﹕ Size: 24576
10-08 14:39:02.809  29233-29233/myapp.realm.io.sizeleak I/REALMTEST﹕ Size: 24576
10-08 14:39:03.209  29233-29233/myapp.realm.io.sizeleak I/REALMTEST﹕ Size: 24576
10-08 14:39:03.649  29233-29233/myapp.realm.io.sizeleak I/REALMTEST﹕ Size: 49152
10-08 14:39:04.049  29233-29233/myapp.realm.io.sizeleak I/REALMTEST﹕ Size: 49152
10-08 14:39:04.449  29233-29233/myapp.realm.io.sizeleak I/REALMTEST﹕ Size: 49152
10-08 14:39:04.839  29233-29233/myapp.realm.io.sizeleak I/REALMTEST﹕ Size: 49152
10-08 14:39:05.329  29233-29233/myapp.realm.io.sizeleak I/REALMTEST﹕ Size: 49152
10-08 14:39:05.709  29233-29233/myapp.realm.io.sizeleak I/REALMTEST﹕ Size: 49152
10-08 14:39:06.259  29233-29233/myapp.realm.io.sizeleak I/REALMTEST﹕ Size: 49152
10-08 14:39:06.689  29233-29233/myapp.realm.io.sizeleak I/REALMTEST﹕ Size: 49152
10-08 14:39:07.109  29233-29233/myapp.realm.io.sizeleak I/REALMTEST﹕ Size: 49152
10-08 14:39:07.589  29233-29233/myapp.realm.io.sizeleak I/REALMTEST﹕ Size: 49152
10-08 14:39:08.019  29233-29233/myapp.realm.io.sizeleak I/REALMTEST﹕ Size: 49152
10-08 14:39:09.129  29233-29233/myapp.realm.io.sizeleak I/REALMTEST﹕ Size: 49152
10-08 14:39:09.729  29233-29233/myapp.realm.io.sizeleak I/REALMTEST﹕ Size: 49152
10-08 14:39:10.169  29233-29233/myapp.realm.io.sizeleak I/REALMTEST﹕ Size: 49152
10-08 14:39:10.669  29233-29233/myapp.realm.io.sizeleak I/REALMTEST﹕ Size: 49152
10-08 14:39:11.049  29233-29233/myapp.realm.io.sizeleak I/REALMTEST﹕ Size: 49152
10-08 14:39:11.449  29233-29233/myapp.realm.io.sizeleak I/REALMTEST﹕ Size: 49152
10-08 14:39:11.849  29233-29233/myapp.realm.io.sizeleak I/REALMTEST﹕ Size: 49152
10-08 14:39:12.269  29233-29233/myapp.realm.io.sizeleak I/REALMTEST﹕ Size: 49152
10-08 14:39:12.269  29233-29233/myapp.realm.io.sizeleak I/REALMTEST﹕ Time: 11265

由于碎片化,预计大小会增加一倍,但我仍然看不到任何可以暗示您的经验的东西。

由于交易量很大,因此时机很高。将它们批处理在一起将大大提高性能:

10-08 14:45:25.009  31593-31593/myapp.realm.io.sizeleak I/REALMTEST﹕ Time: 408
于 2014-10-08T12:17:20.457 回答
6

从 Realm 数据库中删除所有对象:

realm.executeTransaction(new Realm.Transaction() {
    @Override
    public void execute(Realm realm) {
        realm.deleteAll();
    }
});
于 2016-12-06T23:35:23.937 回答
3

您应该删除领域文件。在您第一次使用 Realm 之前,不会创建任何文件。那正是你想要的:

try {
  Realm.deleteRealmFile(context);
  //Realm file has been deleted.
} catch (Exception ex){
  ex.printStackTrace();
  //No Realm file to remove.
}

确保没有使用领域实例。

于 2015-06-06T17:13:19.800 回答
0

好的旧东西,但无论如何。我现在开始在android中使用Realm,我仍在检查它,但是对于过去使用OO数据库的经验,因为可以取消事务,您执行的事务越多,您留下的足迹就越大,以便取消状态的副本必须存在,但您提交是正确的,根据我的经验,问题是某些数据库在提交后不会立即丢弃事务,但这是幕后的东西(我无法确认这一点,只是谈论我以前与其他 OO 的经验可以配置这些设置的数据库)

我在这两个代码中注意到的另一件事是没有人关闭实例,因此(也推测)每个提交事务的领域可能无法获得 GC

再次只是推测希望它有所帮助

于 2015-06-02T21:45:59.413 回答