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:
- Cómo obtener fugas de memoria al cargar imágenes de URl Android
- Cómo tomar instantánea de montón de Xamarin.Android's Mono VM?
- ¿Cómo la CPU y la memoria intensiva es el desarrollo de Android?
- Fuga de memoria, Spring para Android
- Rendimiento de la clase de la clase estática vs no estática de la clase estática de Android
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?
- Vaciado de memoria en el ejemplo práctico
- Cómo obtener uso de la memoria y el uso de la CPU por aplicación?
- Aceleración de hardware OOM androide nativo heap
- ¿Por qué Android 4.0 / Ice Cream Sandwich asigna tanta memoria heap?
- Android: Abrir archivo .hprof En Eclipse
- MAT que identifica una fuga en los elementos de IU que no creé
- ¿Por qué aumenta la memoria heap al volver a iniciar una actividad?
- ¿Es posible declarar una variable de 1 bit en Java?
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:
- Creación de volcados de montón
- Uso de Heap en DDMS
- Usar MAT para comparar / analizar vertederos de montón
- Android: Cuando el teclado en pantalla aparece y desaparece, ¿hay algún oyente que se llama automáticamente?
- Conjunto de conexiones SQLite