2014-10-08 35 views
16

我有一個約30個領域的領域對象,添加和刪除幾個對象後,似乎領域佔用了相當多的空間。所分配的空間的大小似乎有點呈指數增長:正確的方法來清除Realm表/數據庫?

10 *(加100 +刪除所有)= 4 MB的數據

15 *(加100 +刪除所有)= 33 MB的數據

20 *(加100 +刪除所有)= 91 MB的數據

25 *(加100 +刪除所有)= 179 MB的數據

image

文件它data \ data \ app_folder \ files \ default.realm中的自身在此處爲200 MB。

現在這個嚴重的問題可能是因爲我沒有做正確的事情。每次插入之前,我做

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(); 

添加項目到境界是這樣的:

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

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

     realm.commitTransaction(); 
    } 

任何想法?

+0

什麼版本的境界會出現這種情況呢? – Emanuelez 2014-10-08 11:18:15

+0

70.1 ..你也可能想要檢查主頁面上的鏈接,因爲它下載了一個名爲「latest」的擴展名較少的文件(我看到你發佈了71.0,但除了主頁以外的地方下載部分idk從哪裏下載) – chrystolin 2014-10-08 11:25:08

+0

哦,我看到安裝71.0更簡單 – chrystolin 2014-10-08 11:32:47

回答

8

我試着複製一個小模型類(一個字符串,一個int),但沒有成功。

您是否在模型中使用鏈接和/或鏈接列表?我可以看看嗎?

其中一個原因可能是您有例如具有RealmListdogs字段的Person類。 刪除Person類型的所有元素時,Dog現在保留在數據庫中。

編輯:你提供我有點啞數據的嘗試過的數據後:

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 
+0

它是一個reddit提交表示:http://pastebin.com/b8mPTKam和copysubmission處理案件,如果任何領域爲空,因爲我曾經有一個類似的例外,那我不能插入null http://pastebin.com/ur6f7jXW – chrystolin 2014-10-08 12:26:08

+0

可能是錯誤的插入null然後。 :) – chrystolin 2014-10-08 12:52:05

+0

批量交易一起做了幫助,20 * 100後1.5 mb,40 * 100後2,9,60 * 100後3,7 mb,80 * 100交易後4,1mb。在100 * 100之後保持4,1mb。我不知道爲什麼做大量的小交易最終會遇到與一筆大交易相對的大漏洞,但它現在可行,我對此感到滿意,這也是更好的做法。 – chrystolin 2014-10-08 13:01:51

0

好的東西,但無論如何。我現在開始在android中使用Realm了,我仍然在檢查它 ,但對於使用OO數據庫 的過去經驗,因爲可以取消交易,所做的交易越多,您將留下的足跡越大,以便取消國家必須存在,但你的承諾是正確的,根據我的經驗,有些數據庫不會立即放棄交易,但這是幕後的事情(我無法證實這一點,只是談論以前的經驗,我曾與其他面向對象的數據庫,你可以配置這些設置)

另一件我注意到在這兩個代碼是沒有關閉實例 等(也猜測)也許每個提交的交易領域是無法獲得氣相色譜

再次只是猜測 希望它有助於

3

您應該刪除的境界文件。在第一次使用Realm之前,不會創建文件。這就是你想要的:

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

確保沒有使用領域實例。

+6

此答案已過時。 – localhost 2015-12-10 05:40:34

+0

那麼,localhost,你的答案是什麼呢? – 2016-01-04 20:30:52

+3

Realm.getDefaultInstance()。deleteAll(); – Frank 2016-05-31 11:52:39

18

當發生遷移異常(對於dev)時,我已經做了一個簡單的方法來刪除領域數據庫文件。 它還返回一個新的領域實例來防止任何問題。

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. 
     } 
    } 
} 
4

刪除域數據庫中的所有對象:

realm.executeTransaction(new Realm.Transaction() { 
    @Override 
    public void execute(Realm realm) { 
     realm.deleteAll(); 
    } 
});