92 votes

Android: Bitmap recycler() comment ça fonctionne?

Disons que j'ai chargé une image dans un objet bitmap comme

Bitmap myBitmap = BitmapFactory.decodeFile(myFile);

Maintenant ce qui va se passer si je charge une autre image comme

myBitmap = BitmapFactory.decodeFile(myFile2);

Ce qui se passe à la première myBitmap t-il faire de ces Ordures ou je dois manuellement les déchets se rassemblent avant de charger une autre image , par exemple. myBitmap.recycle()

Aussi est-il une meilleure façon de charger des images de grande taille et d'afficher l'un après l'autre de recyclage sur le chemin

81voto

Fedor Points 29890

La première image bitmap n'est pas GC ed lorsque vous décoder le second. GC va le faire plus tard quand elle le décidera. Si vous souhaitez libérer de la mémoire dès que possible, vous devriez téléphoner à recycler() juste avant le décodage de la deuxième image.

Si vous souhaitez charger vraiment grande image, vous devriez ré-échantillonner. Voici un exemple http://stackoverflow.com/questions/477572/android-strange-out-of-memory-issue/823966#823966.

25voto

Timmmm Points 9909

Je pense que le problème est le suivant: Sur la pré-Nid d'abeille versions d'Android, le réel brut bitmap données ne sont pas stockées dans la mémoire virtuelle mais dans natif de la mémoire à la place. Ce natif de la mémoire est libérée lorsque l'java correspondante Bitmap objet du GC.

Toutefois, lorsque vous exécutez hors de natif de la mémoire, le dalvik GC n'est pas déclenché, donc il est possible que votre application utilise très peu de mémoire java, de sorte que le dalvik GC est jamais appelé, mais il utilise des tonnes de mémoire natif pour les bitmaps qui provoque finalement une OOM erreur.

Du moins c'est mon avis. Heureusement, dans le Nid d'abeilles et plus tard, toutes les données de l'image est stockée dans la machine virtuelle de sorte que vous ne devriez pas avoir à utiliser recycle() . Mais pour les millions de 2.3 les utilisateurs (fragmentatiiion secoue poing), vous devez utiliser recycle() dans la mesure du possible (une énorme dispute). Ou sinon, vous pouvez être en mesure d'invoquer le GC à la place.

Ne pas citer de moi sur une de ce!

21voto

djunod Points 1029

Vous aurez besoin de faire appel myBitmap.recycler() avant le chargement de l'image suivante.

Selon la source de votre monfichier (c'est à dire si c'est quelque chose que vous n'avez aucun contrôle sur la taille d'origine), lors du chargement d'une image au lieu de simplement le rééchantillonnage certains nombre arbitraire, vous devez redimensionner l'image à la taille de l'écran.

if (myBitmap != null) {
    myBitmap.recycle();
    myBitmap = null;
}
Bitmap original = BitmapFactory.decodeFile(myFile);
myBitmap = Bitmap.createScaledBitmap(original, displayWidth, displayHeight, true);
if (original != myBitmap)
    original.recycle();
original = null;

Je cache le displayWidth & displayHeight statique que j'ai initialisé au début de mon Activité.

Display display = getWindowManager().getDefaultDisplay();
displayWidth = display.getWidth();
displayHeight = display.getHeight();

11voto

Allen Points 61

Une fois bitmap avait été chargé en mémoire , en fait elle a été faite par les deux partie des données. Première partie à inclure certaines informations sur bitmap , une autre partie d'inclure des informations sur les pixels de l'image( il est maked par tableau d'octets). Première partie existe en Java utilisation de la mémoire, deuxième partie existe en C++ de la mémoire utilisée. Il peut utiliser des uns et des autres de la mémoire directement. Bitmap.recycler() est utilisée pour libérer la mémoire de C++. Si vous ne faites que,le GC de la collection de la partie de java et de la mémoire de C est toujours utilisé.

8voto

Jian Points 51

Timmmm a droit.

selon : http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html

En outre, avant d'Android 3.0 (API de Niveau 11), la sauvegarde des données d'une image bitmap a été stockée en mémoire natif qui n'est pas publié d'une manière prévisible, ce qui peut causer une application brièvement dépasser ses limites de mémoire et de crash.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X