web-dev-qa-db-fra.com

Comment effacer la table / la base de données du domaine?

J'ai un objet de domaine avec ~ 30 champs, après avoir ajouté et supprimé plusieurs objets, il semble que le domaine occupe beaucoup d'espace. La taille de l'espace alloué semble croître quelque peu exponentiellement:

10 * (ajouter 100 + supprimer tout) = 4 Mo de données

15 * (ajouter 100 + supprimer tout) = 33 Mo de données

20 * (ajouter 100 + supprimer tout) = 91 Mo de données

25 * (ajouter 100 + supprimer tout) = 179 Mo de données

image

Le fichier lui-même dans data\data\app_folder\files\default.realm fait 200 Mo à ce stade.

Maintenant, ce problème grave pourrait être dû au fait que je ne fais pas quelque chose correctement. Avant chaque insertion je fais

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

L'ajout d'éléments dans le domaine ressemble à ceci:

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

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

        realm.commitTransaction();
    }

Des idées?

17
chrystolin

J'ai essayé de répliquer avec une petite classe de modèle (une chaîne, une int) sans succès.

Utilisez-vous des liens et/ou des listes de liens dans votre modèle? Puis-je jeter un coup d'oeil?

Une raison pourrait être dans le cas où vous avez par exemple une classe Person qui a un champ RealmListdogs. Lorsque vous supprimez tous les éléments du type Personne, les Chiens sont désormais conservés dans la base de données.

EDIT: Après avoir fourni les données, j'ai essayé avec un peu de données factices:

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

Mais je ne peux toujours pas reproduire:

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

Le doublement de la taille est prévu en raison de la fragmentation, mais je ne vois toujours rien qui puisse suggérer votre expérience.

Le timing est élevé en raison du grand nombre de transactions. Les regrouper augmenterait considérablement les performances:

10-08 14:45:25.009  31593-31593/myapp.realm.io.sizeleak I/REALMTEST﹕ Time: 408
8
Emanuelez

J'ai créé une méthode simple pour supprimer le fichier de base de données de domaine lorsqu'une ne exception de migration se produit (pour dev). Il renvoie également une nouvelle instance de domaine pour éviter tout problème.

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.
        }
    }
}
18
Hugo Gresse

Supprimer tous les objets de la base de données Realm:

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

Vous devez supprimer le fichier de domaine. Jusqu'à la première utilisation de Realm, aucun fichier n'est créé. C'est ce que tu veux:

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

Assurez-vous qu'aucune instance de domaine n'a été utilisée.

3
Rafa0809

ok vieux trucs mais de toute façon. j'ai commencé à utiliser Realm dans Android maintenant et je le vérifie toujours, mais pour les expériences passées en utilisant OO bases de données, car les transactions peuvent être annulées plus vous en avez de transactions) faire le plus grand l'empreinte que vous laisserez, afin d'annuler une copie de l'état doit exister mais vous vous engagez à droite, d'après mon expérience, le problème est que certaines bases de données ne rejettent pas les transactions tout de suite après la validation mais c'est derrière la scène des trucs (je ne peux pas le confirmer, juste parler des expériences précédentes que j'ai eues avec d'autres OO bases de données où vous pouvez configurer ces paramètres)

une autre chose que j'ai remarquée dans les deux codes ici est qu'aucun ne ferme l'instance et donc (spéculant également) peut-être que le royaume de chaque transaction validée ne peut pas obtenir GC

encore une fois en spéculant juste l'espoir que cela aide

0
luis