Je suis en train de créer une application de dessin, principalement pour le plaisir. Mais j'ai rencontré un problème.
Dans mon application, l'utilisateur peut "feuilleter" des croquis qu'il a déjà dessinés. Ces croquis ne sont que des Bitmaps de 400x800. Mais je rencontre constamment des erreurs de mémoire.
Les croquis sont enregistrés sur la carte SD dès que l'utilisateur passe à autre chose, puis ils sont désalloués avec...
if(bitmap != null)
{
bitmap.recycle();
bitmap = null;
}
Ainsi, seulement un ou deux Bitmaps devraient être chargés en mémoire à un moment donné, avant d'être enregistrés et désalloués. Et avec quelques impressions de débogage, j'ai déterminé que c'est vrai (au maximum deux bitmaps en mémoire en même temps). Mon problème est qu'après 14 chargements/désallouages, le programme plante avec une OutOfMemoryError. Toujours 14, peu importe combien de temps je attends entre les "feuillets".
J'ai essayé d'ouvrir DDMS pour voir à quoi ressemble l'allocation mémoire de l'appareil. Étrangement, à chaque fois qu'une image est désallouée, la mémoire va dans la section "inconnue" au lieu de la section "libre". Cela se poursuit jusqu'à ce qu'il ne reste qu'une mince partie de mémoire "libre", moment où le crash se produit (et la mémoire "inconnue" passe à "libre").
Après avoir beaucoup cherché sur Internet, j'ai trouvé quelques ressources qui disent que les bitmaps devraient être désalloués comme prévu, et que les collections de l'ordure Dalvik se produisent toujours avant une erreur de mémoire insuffisante. Et quelques pages diverses ont suggéré que TOUTE la mémoire utilisée par un Bitmap est désallouée lors du GC (tas natif et JVM compris)
Je devrais noter, à ce stade, que je teste sur deux téléphones différents. Motorola Droid X (image d'origine, Android 2.3.3) et Samsung Galaxy S3 (Cyanogenmod 9, Android 4.0.4). Les deux présentent exactement le même comportement. Mes outils Android sont à jour avec toutes les versions du SDK, et j'ai vérifié un million de fois pour m'assurer qu'aucune autre partie de mon code n'effectue d'allocations bizarres (pratiquement rien n'est alloué après le démarrage du programme).
Alors, comment devrais-je désallouer correctement un Bitmap pour qu'il soit libéré (pas seulement "inconnu"), et que je puisse utiliser la mémoire ailleurs? En tant que question supplémentaire, qu'est-ce que ce pool de mémoire "inconnu" et à quoi sert-il?
EDIT : Grammaire et orthographe, ajout de quelques notes sur la plateforme.