Android – BitmapFactory.decodeByteArray – OutOfMemoryError (OOM)

He leído 100s del artículo sobre el problema de MOO. La mayoría se refieren a mapas de bits grandes. Estoy haciendo una aplicación de cartografía donde descargamos azulejos superpuestos 256×256. La mayoría son totalmente transparentes y muy pequeños. Acabo de tener un accidente en un flujo de mapa de bits que fue de 442 bytes de largo al llamar a BitmapFactory.decodeByteArray(....).

La excepción establece:

 java.lang.OutOfMemoryError: bitmap size exceeds VM budget(Heap Size=9415KB, Allocated=5192KB, Bitmap Size=23671KB) 

El código es:

 protected Bitmap retrieveImageData() throws IOException { URL url = new URL(imageUrl); InputStream in = null; OutputStream out = null; HttpURLConnection connection = (HttpURLConnection) url.openConnection(); // determine the image size and allocate a buffer int fileSize = connection.getContentLength(); if (fileSize < 0) { return null; } byte[] imageData = new byte[fileSize]; // download the file //Log.d(LOG_TAG, "fetching image " + imageUrl + " (" + fileSize + ")"); BufferedInputStream istream = new BufferedInputStream(connection.getInputStream()); int bytesRead = 0; int offset = 0; while (bytesRead != -1 && offset < fileSize) { bytesRead = istream.read(imageData, offset, fileSize - offset); offset += bytesRead; } // clean up istream.close(); connection.disconnect(); Bitmap bitmap = null; try { bitmap = BitmapFactory.decodeByteArray(imageData, 0, bytesRead); } catch (OutOfMemoryError e) { Log.e("Map", "Tile Loader (241) Out Of Memory Error " + e.getLocalizedMessage()); System.gc(); } return bitmap; } 

Esto es lo que veo en el depurador:

 bytesRead = 442 

Así que los datos de mapa de bits son 442 bytes. ¿Por qué estaría tratando de crear un mapa de bits 23671KB y quedarse sin memoria?

He tenido problemas como este en el pasado. Android utiliza Bitmap VM y es muy pequeño. Asegúrese de disponer de su mapa de bits a través de bmp.recycle. Versiones posteriores de Android tienen más Bitmap VM, pero la versión que he estado tratando tiene un límite de 20 MB.

Esto puede funcionar. Reducir los mapas de bits a menor calidad. No estoy seguro, pero esto puede duplicar la imagen en la memoria, pero podría fácilmente vale la pena un tiro.

  Bitmap image; image = BitmapFactory.decodeByteArray(data, 0, data.length); Bitmap mutableBitmap = image.copy(Bitmap.Config.ARGB_4444, true); Canvas canvas = new Canvas(mutableBitmap); 

Mi antigua respuesta a continuación no creo que funcionará streaming.

  Options options = new BitmapFactory.Options(); Options options2 = new BitmapFactory.Options(); Options options3 = new BitmapFactory.Options(); options.inPreferredConfig = Bitmap.Config.ARGB_8888;///////includes alpha options2.inPreferredConfig = Bitmap.Config.RGB_565 ;///////no alpha options3.inPreferredConfig = Bitmap.Config.ARGB_4444 ;/////alpha lesser quality image=BitmapFactory.decodeResource(getResources(),R.drawable.imagename,options); image=Bitmap.createScaledBitmap(image, widthx,height, true); 

Parece que ya has hecho algo de lectura sobre este tema, así que te ahorraré los comentarios estándar de 'esto es cómo decodifica un mapa de bits'.

Se me salta que tal vez se está aferrando a una referencia de mapas de bits antiguos (tal vez el mosaico se ha desplazado de la pantalla, pero todavía tiene una referencia en una matriz en algún lugar y como resultado no se está recogiendo basura?) . Esto me ha mordido muy mal en el pasado – las fugas de memoria son difíciles de depurar.

Hay un gran vídeo de E / S de Google por aquí que realmente me ayudó cuando estaba teniendo problemas similares. Es alrededor de una hora, pero esperamos que ahorrar días más tarde. Cubre cosas como:

  1. Creación de volcados de montón
  2. Uso de Heap en DDMS
  3. Usar MAT para comparar / analizar vertederos de montón
  • Uso de la memoria de imagen de fondo Android
  • Cómo corregir este error: java.lang.OutOfMemoryError
  • Descarga memoria móvil
  • ¿Por qué la aplicación y sus recursos se guardan en la memoria después de salir de Android?
  • Java.lang.OutOfMemoryError: tamaño de mapa de bits supera el presupuesto de VM - Android
  • ¿Cómo encontrar una palabra en la lista de palabras grande (vocabulario) con el consumo de memoria de descenso y el tiempo de búsqueda?
  • Drawable vs Single reutilizable Bitmap mejor con la memoria?
  • ¿Cuál de estas 2 opciones es mejor para el rendimiento?
  • Carga el sonido de la memoria en Android
  • ¿Hay una manera de compactar memoria en android para bajar la marca de agua alta?
  • Cómo liberar la memoria del mapa de bits utilizando imageloader en android?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.