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
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?
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
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.
}
}
}
Supprimer tous les objets de la base de données Realm:
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.deleteAll();
}
});
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.
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