Android: Comment fonctionne Bitmap recycle ()?

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

Bitmap myBitmap = BitmapFactory.decodeFile(myFile);

maintenant, que se passera-t-il si je charge un autre bitmap comme

myBitmap = BitmapFactory.decodeFile(myFile2);

que se passe-t-il avec le premier myBitmap? Est-ce Qu'il est collecté ou est-ce que je dois le faire manuellement avant de charger un autre bitmap, par exemple. myBitmap.recycle() ?

aussi, est-il une meilleure façon de charger de grandes images et de les afficher l'un après l'autre tout en recyclant sur le chemin?

74
demandé sur LAD 2010-09-29 20:39:05

5 réponses

le premier bitmap n'est pas GC'ed lorsque vous décodez le second. Le CA le fera plus tard quand il le décidera. Si vous voulez libérer la mémoire aussi vite que possible, vous devez appeler recycle() juste avant de décoder le second bitmap.

si vous voulez charger une image vraiment grande, vous devez la rééchantillonner. Voici un exemple étrange de problème de mémoire lors du chargement d'une image sur un objet Bitmap .

64
répondu Fedor 2017-05-23 12:02:11

vous devrez appeler myritmap.recycle () avant de charger l'image suivante.

dépend de la source de votre myFile (par ex. 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 rééchantillonner un certain nombre arbitraire, vous devriez échelle l'image à la taille de l'affichage.

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();
20
répondu djunod 2016-09-30 18:36:31

je pense que le problème est celui-ci: sur les versions pré-Honeycomb D'Android, les données brutes bitmap réelles ne sont pas stockées dans la mémoire VM mais dans la mémoire native à la place. Cette mémoire native est libérée lorsque l'objet java correspondant Bitmap est GC'D.

cependant , quand vous manquez de mémoire native, le GC de dalvik n'est pas déclenché, il est donc possible que votre application utilise très peu de la mémoire java, donc le GC de dalvik est jamais invoqué, mais il utilise des tonnes de mémoire native pour bitmaps qui provoque éventuellement une erreur OOM.

du moins, c'est mon avis. Heureusement dans Honeycomb et plus tard, toutes les données bitmap sont stockées dans la VM donc vous ne devriez pas avoir à utiliser recycle() du tout. Mais pour les millions d'utilisateurs de 2.3 (fragmentation shakes fist ), vous devez utiliser recycle() chaque fois que possible (un énorme tracas). Ou encore, vous pourriez être en mesure d'invoquer le GC à la place.

19
répondu Timmmm 2017-08-07 16:36:58

une fois bitmap chargé en mémoire , en fait il a été fait par deux données de partie. La première partie contient des informations sur bitmap , la Seconde des informations sur les pixels de bitmap (elle est maquillée par un tableau octet). La première partie existe dans la mémoire Java used, la deuxième partie existe dans la mémoire C++ used. Il peut utiliser la mémoire de l'autre directement. Bitmap.recycler() est utilisée pour libérer la mémoire de C++. Si vous ne faites que cela,le GC va collecter la partie de java et la mémoire de C est toujours utiliser.

10
répondu Allen 2012-05-22 08:15:37

Timmmm avait raison.

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

de plus, Avant Android 3.0 (API Niveau 11), les données de support d'un bitmap ont été stockées dans la mémoire native qui n'est pas libérée de manière prévisible, ce qui peut causer une application de dépasser brièvement ses limites de mémoire et de plantage.

8
répondu Jian 2013-04-18 14:51:20