Android: BitmapFactory.decodeStream() de la mémoire avec une 400KB fichier avec 2 mo de libre tas
Mon application est de frapper un OOM erreur à la ligne suivante dans la source:
image = BitmapFactory.decodeStream(assetManager.open(imgFilename));
Juste avant l'allocation qui entraîne l'application à être tués avec un OOM erreur:
(...)
08-05 21:22:12.443: I/dalvikvm-heap(2319): Clamp target GC heap from 25.056MB to 24.000MB
08-05 21:22:12.443: D/dalvikvm(2319): GC_FOR_MALLOC freed <1K, 50% free 2709K/5379K, external 18296K/19336K, paused 58ms
08-05 21:22:14.513: D/dalvikvm(2319): GC_EXTERNAL_ALLOC freed <1K, 50% free 2709K/5379K, external 18296K/19336K, paused 101ms
08-05 21:22:14.903: I/dalvikvm-heap(2319): Clamp target GC heap from 25.073MB to 24.000MB
08-05 21:22:14.903: D/dalvikvm(2319): GC_FOR_MALLOC freed 0K, 50% free 2709K/5379K, external 18312K/19336K, paused 53ms
08-05 21:22:22.843: D/ddm-heap(2319): Heap GC request
08-05 21:22:22.963: I/dalvikvm-heap(2319): Clamp target GC heap from 25.073MB to 24.000MB
08-05 21:22:22.963: D/dalvikvm(2319): threadid=1: still suspended after undo (sc=1 dc=1)
08-05 21:22:22.963: D/dalvikvm(2319): GC_EXPLICIT freed 1K, 50% free 2710K/5379K, external 18312K/19336K, paused 116ms
DDMS rapports une image similaire à propos de l'état de la pile:
Heap Size: 5.254 MB
Allocated: 2.647 MB
Free: 2.607 MB
%Used: 50.38%
#Objects 49,028
Le pas à pas sur cette ligne les résultats dans un OOM erreur:
08-05 21:26:04.783: D/dalvikvm(2319): GC_EXTERNAL_ALLOC freed <1K, 50% free 2710K/5379K, external 18312K/19336K, paused 57ms
08-05 21:26:05.023: E/dalvikvm-heap(2319): 2097152-byte external allocation too large for this process.
08-05 21:26:05.163: I/dalvikvm-heap(2319): Clamp target GC heap from 25.073MB to 24.000MB
08-05 21:26:05.163: E/GraphicsJNI(2319): VM won't let us allocate 2097152 bytes
08-05 21:26:05.163: D/dalvikvm(2319): GC_FOR_MALLOC freed 0K, 50% free 2710K/5379K, external 18312K/19336K, paused 30ms
08-05 21:26:05.283: D/skia(2319): --- decoder->decode returned false
- La taille du fichier référencé par "imgFileName" est signalé à être < 400K sur Windows. Alors, pourquoi ne BitmapFactory.decodeStream essayer d'allouer 2 MO?
- Pourquoi est-il un OOM erreur quand il semble y avoir suffisamment d'espace libre?
Cette application est de ciblage Android 2.2 et plus.
Merci d'avance!
Vous devez vous connecter pour publier un commentaire.
Android bibliothèque n'est pas si intelligent pour le chargement des images, de sorte que vous avez à créer des solutions de contournement pour ce.
Dans mes tests,
Drawable.createFromStream
utilise plus de mémoire queBitmapFactory.decodeStream
.Vous pouvez changer le schéma de Couleur pour la réduction de la mémoire (RGB_565), mais l'image sera trop perdre en qualité:
Référence: http://developer.android.com/reference/android/graphics/Bitmap.Config.html
Vous pouvez également charger une image à l'échelle, ce qui va diminuer de beaucoup l'utilisation de la mémoire, mais vous devez savoir que vos images afin de ne pas perdre trop de qualité.
Référence: http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html
Pour définir la inSampleSize de façon dynamique, vous voudrez peut-être savoir la taille de l'image pour prendre votre décision:
Vous pouvez personnaliser la inSampleSize selon la taille de l'écran de l'appareil. Pour obtenir la taille de l'écran, vous pouvez faire:
D'autres tutoriels:
- http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
- http://developer.android.com/training/displaying-bitmaps/index.html
Veuillez consulter ce guide sur le chargement d'un grand Bitmaps de manière plus efficace:
http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
400 KO fichier image peut facilement prendre de 5 à 10 MO de RAM.
La taille du fichier sur le disque ne doit pas nécessairement coïncider avec la taille du fichier en mémoire. Les Chances sont probablement que le fichier est compressé, ce qui ils ne seront pas lors du décodage. Vous devez en tenir compte dans votre calcul.
Multiplier la taille de l'image (largeur x hauteur) par la profondeur de couleur de l'image pour avoir la taille en mémoire de l'image.
Fondamentalement, vous pouvez résoudre votre problème en essayant de mettre à l'échelle votre
Bitmap
et vous verrez la consommation de mémoire réduite. Pour le faire, vous pouvez copier il de la méthode montré ici.Aussi, il y a une page dédiée à Android Developeres qui pourraient vous aider à mieux comprendre comment charger les grandes images bitmap. Jetez un oeil à la officiel la documentation.
Alors que les réponses ci-dessus sont évidemment correct, une meilleure pratique est également de mettre en explicitement l'ImageView bitmap/src propriété null, quand elles ne sont plus utilisées, surtout si votre activité est en train d'être détruit.
Toute autre heavy duty ressources( grand texte, audio, vidéo), etc. peut également être annulé.
Cela garantit que les ressources sont libérées immédiatement et ne pas attendre que la GC à collecter.
J'ai résolu OutOfMemoryError question en utilisant la méthode ci-dessous
- Je changer la insample taille par 2. Mon problème est résolu. Mais assurez-vous que la qualité de l'image n'ya pas de détruire.