Je rencontre des problèmes pour trouver une fuite de mémoire dans mon application Mono pour Android. Je crois que je suis toutes les meilleures pratiques, décrites plus tard, mais je continue à obtenir OutOfMemoryError après un nombre cohérent et reproductible de run-throughs d'une activité. En utilisant ddms
sur l'émulateur, je peux voir que mon application consomme environ 200 "objets de données" supplémentaires et environ 30 Ko de mémoire chaque fois que notre ViewFlipper
retourne à la page suivante. Nous consommons également d'autres ressources, mais à un taux beaucoup plus bas. J'utilise le ViewFlipper
un peu peu conventionnel; il retourne dans une seule direction, et retirez le View
s qui ont déjà été montré:Mono pour Android - OutOfMemoryError
while (flipper.ChildCount > 2)
{
flipper.RemoveViewAt(0);
}
J'ai pris grand soin de Dispose()
de toute référence à toutes les View
s que nous avons utilisé, comme described in this blog post. J'utilise using
religieusement pour tous les composants de l'interface utilisateur (qui Dispose()
automatiquement l'objet à la fin du champ d'application):
using (TextView questionView = header.FindViewById<TextView>(Resource.Id.question))
{
questionView.Text = question.Text;
}
Cela ne semble pas avoir d'effet sur la fuite de mémoire. J'utilise le même modèle chaque fois que je charge Bitmap
s (généralement des fichiers PNG de moins de 20 Ko), ce que je fais assez souvent.
Mise à jour: je charge bitmaps en utilisant une méthode d'extension:
public static Bitmap BitmapFromAsset(this Context context, String asset)
{
Bitmap bitmap;
using (Stream stream = context.Assets.Open(asset))
{
bitmap = BitmapFactory.DecodeStream(stream);
stream.Close();
}
return bitmap;
}
Les bitmaps sont ensuite utilisés comme ceci:
using (Bitmap b = this.BitmapFromAsset(path))
{
imageView.SetImageBitmap(b);
}
Mise à jour: Comme Aranda suggère ci-dessous, j'utiliser des délégués , donc c'est un modèle commun dans mon code:
using (View button = FindViewById(Resource.Id.button))
{
button.Click += delegate
{
// do something
};
}
Modification de ce que je supprime les gestionnaires lorsque le View
est supprimé ne fait aucune différence dans la fuite.
Mise à jour: Bug posted with Xamarin with example project.
Oui, j'utilise delegate pour attacher aux différents 'View's. Donc, je dois supprimer tous les gestionnaires d'événements qui utilisent des délégués, ou tous les gestionnaires d'événements en général? Supposons que vous ayez ceci: 'en utilisant (Bouton b = FindViewById
Même en supprimant les gestionnaires Click de l'équation, j'ai toujours des fuites de mémoire comme décrit ci-dessus. –
Intéressant. Votre exemple particulier ne provoquerait pas de fuite car le délégué est une méthode anonyme et serait dans la portée de l'instance de vue elle-même. Je pense que je ne me suis pas bien expliqué non plus. La mienne coulait parce que mon GameScreen avait attaché une de ses méthodes à un événement (ou un délégué) dans ma classe Engine. Le moteur tenait toujours une référence à la classe GameScreen via l'événement joint.Pas forcément quoi que ce soit à voir avec votre fuite :( – Aranda