ventajas vectorial usos que procesamiento mapas mapa graficacion formatos dibujo desventajas colores android memory-leaks

android - vectorial - que es un mapa de bits



java.lang.OutOfMemoryError: el tamaƱo del mapa de bits excede el presupuesto de VM (12)

¿De dónde viene la fuente de la imagen? ¿Tienes una imagen de 9MB en tu carpeta de drawables?

Hay mucha discusión sobre problemas con la administración de memoria de mapa de bits nativa de Android, por ejemplo, http://code.google.com/p/android/issues/detail?id=8488 , http://code.google.com/p/android/issues/detail?id=8488 , http://groups.google.com/group/android-developers/browse_thread/thread/ed57849ef705d421/11af8362d77a8cf4?lnk=raot . He tenido la suerte de invocar explícitamente recycle () y System.gc () cada vez que termino con un mapa de bits, por ejemplo:

private void changeImage() { if (mCurrentImage != null) { mCurrentImage.recycle(); mCurrentImage = null; System.gc(); } mCurrentImage = getNewImage(); }

Estoy intentando cambiar el diseño de mi aplicación de vertical a horizontal y viceversa. Pero si lo hago con frecuencia o más de una vez, a veces mi aplicación falla. A continuación se muestra el registro de errores. Por favor sugiere que se puede hacer?

01-06 09:52:27.787: ERROR/dalvikvm-heap(17473): 1550532-byte external allocation too large for this process. 01-06 09:52:27.787: ERROR/dalvikvm(17473): Out of memory: Heap Size=6471KB, Allocated=4075KB, Bitmap Size=9564KB 01-06 09:52:27.787: ERROR/(17473): VM won''t let us allocate 1550532 bytes 01-06 09:52:27.798: DEBUG/skia(17473): --- decoder->decode returned false 01-06 09:52:27.798: DEBUG/AndroidRuntime(17473): Shutting down VM 01-06 09:52:27.798: WARN/dalvikvm(17473): threadid=3: thread exiting with uncaught exception (group=0x4001e390) 01-06 09:52:27.807: ERROR/AndroidRuntime(17473): Uncaught handler: thread main exiting due to uncaught exception 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): java.lang.RuntimeException: Unable to start activity ComponentInfo{}: android.view.InflateException: Binary XML file line #2: Error inflating class <unknown 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2596) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2621) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3812) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.app.ActivityThread.access$2300(ActivityThread.java:126) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1936) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.os.Handler.dispatchMessage(Handler.java:99) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.os.Looper.loop(Looper.java:123) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.app.ActivityThread.main(ActivityThread.java:4595) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at java.lang.reflect.Method.invokeNative(Native Method) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at java.lang.reflect.Method.invoke(Method.java:521) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at dalvik.system.NativeStart.main(Native Method) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): Caused by: android.view.InflateException: Binary XML file line #2: Error inflating class <unknown 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.view.LayoutInflater.createView(LayoutInflater.java:513) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:563) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.view.LayoutInflater.inflate(LayoutInflater.java:385) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.view.LayoutInflater.inflate(LayoutInflater.java:320) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.view.LayoutInflater.inflate(LayoutInflater.java:276) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:207) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.app.Activity.setContentView(Activity.java:1629) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at onCreate(Game.java:98) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2544) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): ... 12 more 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): Caused by: java.lang.reflect.InvocationTargetException 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.widget.LinearLayout.<init>(LinearLayout.java:92) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at java.lang.reflect.Constructor.constructNative(Native Method) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at java.lang.reflect.Constructor.newInstance(Constructor.java:446) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.view.LayoutInflater.createView(LayoutInflater.java:500) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): ... 22 more 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:464) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:340) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.content.res.Resources.loadDrawable(Resources.java:1705) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.content.res.TypedArray.getDrawable(TypedArray.java:548) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.view.View.<init>(View.java:1850) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.view.View.<init>(View.java:1799) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.view.ViewGroup.<init>(ViewGroup.java:296) 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): ... 26 more


Agregue esta línea de código al archivo de manifiesto de Android dentro de la etiqueta de "aplicación": - android: largeHeap = "true"

<application android:theme="@android:style/Theme.NoTitleBar" android:allowBackup="true" android:largeHeap="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" >




Esta es una respuesta práctica, lo que traté de evitar este problema en tiempo de ejecución

Runtime.getRuntime().gc();

Llamar al recolector de basura es una buena idea.


Hice un par de extensiones a la excelente respuesta de @ hp.android:

  1. En lugar de definir un ID RootView en cada clase XML, encuentro dinámicamente la vista raíz usando android.R.id.content .
  2. Como dice @Mario Lenci, AdapterView no es compatible con removeAllViews, por lo que verifico el tipo de vista antes de llamar a removeAllViews() .
  3. IMO no es una buena idea llamar a System.gc() en cada llamada a onDestroy (por ejemplo, esta respuesta ), así que lo eliminé.
  4. He creado un método estático onDestroy que llamo desde onDestroy en todas mis clases de actividad personalizadas.
  5. He agregado protección y registro extra de errores.

Aquí está el código:

public static void onDestroy(Activity activity) { View rootView = null; try { rootView = ((ViewGroup) activity.findViewById(android.R.id.content)) .getChildAt(0); } catch (Exception e) { Log.w("Cannot find root view to call unbindDrawables on", activity); } if (rootView != null) { Log.d("unbindDrawables", activity, rootView); unbindDrawables(rootView); } } /** * Utility method to unbind drawables when an activity is destroyed. This * ensures the drawables can be garbage collected. */ public static void unbindDrawables(View view) { if (view.getBackground() != null) { view.getBackground().setCallback(null); } if (view instanceof ViewGroup) { for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) { unbindDrawables(((ViewGroup) view).getChildAt(i)); } try { // AdapterView objects do not support the removeAllViews method if (!(view instanceof AdapterView)) { ((ViewGroup) view).removeAllViews(); } } catch (Exception e) { Log.w("Ignore Exception in unbindDrawables", e); } } }


Obtuve java.lang.OutOfMemoryError: el tamaño del mapa de bits supera el error del presupuesto de VM en varias ocasiones

1) Al cambiar de la aplicación y volver a la aplicación algún tiempo después (presione el botón de inicio y después de navegar por alguna URL)

2) Cuando inicia o cierra sesión en la aplicación con frecuencia (en 10 segundos)

3) Al cambiar el dispositivo horizontal / verticalmente

Finalmente resolví el error de la siguiente manera

public void clearAllResources() { // Set related variables null System.gc(); Runtime.getRuntime().gc(); }


Primero, detenga su aplicación para que no se bloquee durante el tiempo de ejecución detectando el error OutOfMemory en el lugar que cree que puede generar este error de la siguiente manera:

try { ... } catch(OutOfMemoryError error) { //decide what to do when there is not more memory available }


Puede solucionar el problema usando opts.inSampleSize=2; or opts.inSampleSize=4 opts.inSampleSize=2; or opts.inSampleSize=4

BitmapFactory.Options opts = new BitmapFactory.Options(); // opts.inJustDecodeBounds = true; opts.inSampleSize=2; Bitmap myBitmap = BitmapFactory.decodeFile(st_imagepath,opts);


Una asignación de 1550532 bytes parece grande. Supongo que su diseño tiene una referencia a una imagen de mapa de bits de algún tipo, tal vez un PNG. ¿Cuáles son las dimensiones de este PNG? Si es realmente grande y tienes más de un par, es posible que no tengas suficiente memoria para cargarlos todos a la vez.

Además, si esto se desencadena por la rotación, recuerde que su Actividad se destruye y recrea, por lo que es posible que tenga que tener cuidado con las referencias estáticas. Echa un vistazo a esta publicación de blog de Google . Deberá tener cuidado de mantener referencias estáticas a las cosas en su código que pueden ocasionar fugas


Uno de los errores más comunes que encontré desarrollando aplicaciones de Android es el

java.lang.OutOfMemoryError: el tamaño del mapa de bits supera el presupuesto de VM

error. Encontré este error con frecuencia en Actividades que usan muchos mapas de bits después de cambiar de orientación: la Actividad se destruye, se crea de nuevo y los diseños se "inflan" desde el XML que consume la memoria VM disponible para mapas de bits.

Los mapas de bits en el diseño de actividad anterior no son desasignados correctamente por el recolector de basura porque han cruzado referencias a su actividad. Después de muchos experimentos, encontré una solución bastante buena para este problema.

Primero, configure el atributo "id" en la vista principal de su diseño XML:

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/RootView"> ...

Luego, en el método onDestroy() de su Actividad, llame al método unbindDrawables() pasando una referencia a la Vista padre y luego haga un System.gc() .

@Override protected void onDestroy() { super.onDestroy(); unbindDrawables(findViewById(R.id.RootView)); System.gc(); } private void unbindDrawables(View view) { if (view.getBackground() != null) { view.getBackground().setCallback(null); } if (view instanceof ViewGroup) { for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) { unbindDrawables(((ViewGroup) view).getChildAt(i)); } ((ViewGroup) view).removeAllViews(); } }

Este método unbindDrawables() explora el árbol de vista recursivamente y:

  1. Elimina las devoluciones de llamada en todos los diseños arrastrables
  2. Elimina niños en cada grupo de vista