Java 清除领域表/数据库的正确方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26254881/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Proper way to clear Realm table/database?
提问by chrystolin
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:
我有一个包含约 30 个字段的领域对象,在添加和删除几个对象之后,领域似乎占用了相当多的空间。分配空间的大小似乎呈指数增长:
10*(add 100 + remove all) = 4 mb Data
10*(添加 100 + 全部删除)= 4 mb 数据
15*(add 100 + remove all) = 33 mb Data
15*(添加 100 + 全部删除)= 33 mb 数据
20*(add 100 + remove all) = 91 mb Data
20*(添加 100 + 全部删除)= 91 mb 数据
25*(add 100 + remove all) = 179 mb Data
25*(添加 100 + 全部删除)= 179 mb 数据
The file itself in data\data\app_folder\files\default.realm is 200 mb at this point.
此时 data\data\app_folder\files\default.realm 中的文件本身为 200 mb。
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?
有任何想法吗?
采纳答案by Emanuelez
I tried replicating with a small model class (one String, one int) with no success.
我尝试用一个小的模型类(一个字符串,一个整数)进行复制,但没有成功。
Do you use Links and/or LinkLists in your model? Can I take a look at it?
您是否在模型中使用链接和/或链接列表?我可以看看吗?
One reason might be in the case you have for example a Person class that has a RealmListdogs field. When you delete all the elements of the Person type the Dogs are right now retained in the database.
一个原因可能是例如您有一个具有 RealmListdogs 字段的 Person 类。当您删除 Person 类型的所有元素时,Dogs 现在保留在数据库中。
EDIT: After you provided the data I tried with a bit of dummy data:
编辑:在您提供数据后,我尝试使用一些虚拟数据:
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));
But I still cannot reproduce:
但我仍然无法重现:
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
The size doubling is expected because of fragmentation, but I still see nothing that can suggest your experience.
由于碎片化,预计大小会翻倍,但我仍然看不到任何可以暗示您的体验的东西。
The timing is high because of the large number of transactions. Batching them together would increase performance considerably:
由于交易量大,时间很长。将它们批处理将大大提高性能:
10-08 14:45:25.009 31593-31593/myapp.realm.io.sizeleak I/REALMTEST﹕ Time: 408
回答by luis
ok old stuff but anyway. i started to use Realm in android now and i'm still checking it out but for past experiences using OO databases since transactions can be cancelled the more transactions you do the bigger the footprint you will leave, in order to cancel a copy of the state must exist but you are commiting right, from my experience the prob is that some databases do not discard the transactions right away after commiting but this is behind the scene stuff (i cannot confirm this, just talking about previous experiences that i had with other OO databases where you could config these settings)
好的旧东西,但无论如何。我现在开始在 android 中使用 Realm,我仍在检查它,但对于过去使用 OO 数据库的经验,因为事务可以取消,你做的事务越多,你留下的足迹就越大,以便取消状态的副本必须存在,但您提交正确,根据我的经验,问题是某些数据库在提交后不会立即丢弃事务,但这是幕后的事情(我无法确认这一点,只是谈论我以前与其他 OO 的经历您可以在其中配置这些设置的数据库)
another thing that i noticed in both codes here is that none closes the instance and so (also speculating) maybe the Realm of each commited transaction is not being able to get GC
我在这里的两个代码中注意到的另一件事是没有关闭实例,因此(也推测)也许每个提交的事务的领域无法获得 GC
again just speculating hope it helps
再次只是推测希望它有帮助
回答by Rafa0809
You should delete the Realm file. Until first time you use Realm no file is created. That's what you want:
您应该删除 Realm 文件。在您第一次使用 Realm 之前,不会创建任何文件。那就是你想要的:
try {
Realm.deleteRealmFile(context);
//Realm file has been deleted.
} catch (Exception ex){
ex.printStackTrace();
//No Realm file to remove.
}
Be sure no realm instance is been used.
确保没有使用领域实例。
回答by Hugo Gresse
I've made a simple method to delete the realm database file when a migration exception occur(for dev). It also return a new realm instance to prevent any issue.
我已经做了一个简单的方法来在发生迁移异常时删除领域数据库文件(对于开发者)。它还返回一个新的领域实例以防止出现任何问题。
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.
}
}
}
回答by Fran Bolado
Delete all objects from Realm database:
从 Realm 数据库中删除所有对象:
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.deleteAll();
}
});