tengo - Error de falta de memoria en Android
mi celular dice memoria llena y esta vacia (2)
Reciclar bitmaps cuando no esté en uso. Después de los mapas de bits en panal, mantente en el montón.
bitmaps.recycle();
http://android-developers.blogspot.de/2009/01/avoiding-memory-leaks.html .
El enlace de arriba tiene un tema sobre cómo evitar fugas de memoria.
Además, si tienes una imagen de alta resolución, debes reducirla. Consulte el tema en Cargar una versión reducida en la memoria.
http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
Supongamos que navega de la actividad A a la B. En onResume () carga mapas de bits. En onPause () recicla bitmaps. Haga esto para cada actividad donde cargue bitmaps.
Puede usar MAT Analyzer como complemento en el siguiente video para analizar y corregir las filtraciones de memeory http://www.youtube.com/watch?v=_CruQY55HOk
Puede usar android: largeHeap en manifiesto bajo la etiqueta de la aplicación.
Advertencia: a medida que aumenta el tamaño del almacenamiento dinámico, el GC se activa más frecuentemente y con más frecuencia se detiene la aplicación. Entonces, solo porque requieres un montón más grande, no deberías usar esto. Puedes ver el video de arriba y el chico te advierte lo mismo.
android:largeHeap
Si los procesos de su aplicación se deben crear con un gran montón de Dalvik. Esto se aplica a todos los procesos creados para la aplicación. Solo se aplica a la primera aplicación cargada en un proceso; si está usando una identificación de usuario compartida para permitir que varias aplicaciones utilicen un proceso, todas deben usar esta opción de forma consistente o tendrán resultados imprevisibles.
La mayoría de las aplicaciones no deberían necesitar esto y deberían enfocarse en reducir el uso general de memoria para un mejor rendimiento. Habilitar esto tampoco garantiza un aumento fijo en la memoria disponible, porque algunos dispositivos están limitados por su memoria total disponible .
Para consultar el tamaño de memoria disponible en tiempo de ejecución, use los métodos getMemoryClass () o getLargeMemoryClass ().
Estoy desarrollando una aplicación de juego para Android donde tengo alrededor de 15 pantallas. Cuando juego continuamente, aparece un problema de error de falta de memoria de forma aleatoria, a veces en la pantalla 15 y, a veces, en la pantalla 12 o más.
Además, consulte el xml a continuación, de una de las pantallas.
<?xml version="1.0" encoding="UTF-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/MainFrame"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<RelativeLayout
android:id="@+id/mainlayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/woodenbg1" >
<Chronometer
android:id="@+id/chronometer"
android:layout_width="0dp"
android:layout_height="0dp"
android:textSize="20sp"
android:textStyle="bold"
android:typeface="sans"
android:visibility="gone" />
<ImageView
android:id="@+id/imageline"
android:layout_width="10000dp"
android:layout_height="wrap_content"
android:layout_marginTop="105dp"
android:src="@drawable/lineblackfornormal" />
<ImageView
android:id="@+id/imageviewunderalphac"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="350dp"
android:src="@drawable/whitec" />
<ImageView
android:id="@+id/backgroundofalphab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="35dp"
android:src="@drawable/backgroundfordragimages"
android:visibility="invisible" />
<ImageView
android:id="@+id/backgroundofalphaa"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginTop="35dp"
android:src="@drawable/backgroundfordragimages"
android:visibility="invisible" />
<ImageView
android:id="@+id/backgroundofalphac"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginTop="33dp"
android:src="@drawable/backgroundfordragimages"
android:visibility="invisible" />
<ImageView
android:id="@+id/imageviewunderleftalphab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="250dp"
android:layout_marginLeft="15dp"
android:src="@drawable/whiteb" />
<ImageView
android:id="@+id/imageviewunderrightalphaa"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="250dp"
android:layout_marginRight="10dp"
android:src="@drawable/whitea" />
<ImageView
android:id="@+id/imageviewabovealphab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="35dp"
android:src="@drawable/colouredb" />
<ImageView
android:id="@+id/imageviewabovealphaa"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginTop="35dp"
android:src="@drawable/coloureda" />
<ImageView
android:id="@+id/imageviewabovealphac"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/backgroundofalphac"
android:layout_marginTop="33dp"
android:src="@drawable/colouredc" />
</RelativeLayout>
</FrameLayout>
Logcat
05-16 12:22:18.989: E/GraphicsJNI(6745): VM won''t let us allocate 2225664 bytes
05-16 12:22:18.999: E/AndroidRuntime(6745): FATAL EXCEPTION: main
05-16 12:22:18.999: E/AndroidRuntime(6745): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
05-16 12:22:18.999: E/AndroidRuntime(6745): at android.graphics.Bitmap.nativeCreate(Native Method)
05-16 12:22:18.999: E/AndroidRuntime(6745): at android.graphics.Bitmap.createBitmap(Bitmap.java:477)
05-16 12:22:18.999: E/AndroidRuntime(6745): at android.graphics.Bitmap.createBitmap(Bitmap.java:444)
05-16 12:22:18.999: E/AndroidRuntime(6745): at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:349)
05-16 12:22:18.999: E/AndroidRuntime(6745): at android.graphics.BitmapFactory.finishDecode(BitmapFactory.java:498)
05-16 12:22:18.999: E/AndroidRuntime(6745): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:473)
05-16 12:22:18.999: E/AndroidRuntime(6745): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:336)
05-16 12:22:18.999: E/AndroidRuntime(6745): at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697)
05-16 12:22:18.999: E/AndroidRuntime(6745): at android.content.res.Resources.loadDrawable(Resources.java:1709)
05-16 12:22:18.999: E/AndroidRuntime(6745): at android.content.res.Resources.getDrawable(Resources.java:581)
05-16 12:22:18.999: E/AndroidRuntime(6745): at android.view.View.setBackgroundResource(View.java:7533)
05-16 12:22:18.999: E/AndroidRuntime(6745): at com.ssn.myapp.NumbersLevel3.onCreate(NumbersLevel3.java:173)
05-16 12:22:18.999: E/AndroidRuntime(6745): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
05-16 12:22:18.999: E/AndroidRuntime(6745): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
05-16 12:22:18.999: E/AndroidRuntime(6745): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
05-16 12:22:18.999: E/AndroidRuntime(6745): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:2832)
05-16 12:22:18.999: E/AndroidRuntime(6745): at android.app.ActivityThread.access$1600(ActivityThread.java:117)
05-16 12:22:18.999: E/AndroidRuntime(6745): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
05-16 12:22:18.999: E/AndroidRuntime(6745): at android.os.Handler.dispatchMessage(Handler.java:99)
05-16 12:22:18.999: E/AndroidRuntime(6745): at android.os.Looper.loop(Looper.java:130)
05-16 12:22:18.999: E/AndroidRuntime(6745): at android.app.ActivityThread.main(ActivityThread.java:3683)
05-16 12:22:18.999: E/AndroidRuntime(6745): at java.lang.reflect.Method.invokeNative(Native Method)
05-16 12:22:18.999: E/AndroidRuntime(6745): at java.lang.reflect.Method.invoke(Method.java:507)
05-16 12:22:18.999: E/AndroidRuntime(6745): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
05-16 12:22:18.999: E/AndroidRuntime(6745): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
05-16 12:22:18.999: E/AndroidRuntime(6745): at dalvik.system.NativeStart.main(Native Method)
Es porque sus imágenes no se desasignan cuando se destruye su actividad.
Refiere esta respuesta. También este enlace también.
No creo que deba preocuparse por los detalles granulares cuando se ejecuta GC, ya que no tenemos control sobre cuándo se llama a gc. Incluso llamar a gc () no garantiza una recopilación. Según la documentación de System.gc ()
Memmory is exceeded. GC automatically collects all unused bitmaps. So voluntarily we have to remove it
Indica a la máquina virtual que sería un buen momento para ejecutar el recolector de elementos no utilizados. Tenga en cuenta que esto es solo una pista. No hay garantía de que el recolector de basura se ejecute realmente.
Al desarrollar la aplicación con asignación de objetos grandes, me preocuparía lo siguiente:
- Al asignar el objeto grande y, posteriormente, después de salir del alcance del ciclo de vida de ese objeto, ¿lo veo recuperado por el GC en actividades posteriores? Esto podría verificarse fácilmente ejecutando dumpsys meminfo con adb shell. Básicamente, verifique después de la desasignación si la memoria está correctamente recogida de basura, lo que suele significar un pico grande y una caída posterior.
- Compruebe si este objeto grande tiene una ruta clara hacia GC. Puede hacer esto al verificar la ruta de referencia de este objeto al descargar el archivo hprof y verificarlo en el Analizador de memoria. Si lo hace, está seguro ya que el GC lo suficientemente inteligente como para recoger.
- Después de asignar este objeto grande, ¿tengo suficiente relleno en mi pila para ejecutar la actividad posterior? Si el objeto es demasiado grande, existe la posibilidad de que GC no sea lo suficientemente rápido como para recopilarlo (esto está relacionado con tu punto) y el consumo de memoria de la actividad posterior combinado con el sobrante de los anteriores podría en realidad causar error de memoria Establecer null con una ruta clara a GC ayudará a garantizar que este objeto obtenga GC''ed apropiadamente. Admito que esto es un problema, pero mi opinión es que si esto se convierte en un problema, deberíamos reconsiderar cómo está diseñada esta sección en particular y ver si podemos hacer alguna optimización al respecto.
- Implemente la limpieza de la actividad a través de onDestroy según sea necesario y asegúrese de que la actividad no sea referenciada por otros para que pueda obtenerse correctamente la basura recolectada. Por ejemplo: a menudo pasamos el contexto de la actividad al olvidar que mantendrá su referencia. Cosas como llamar a recycle () en bitmap también deberían ayudar. Recordar estos puntos debería ayudar a preparar más espacio en el caso de que ocurra el n. ° 3
Espero que esto te pueda ayudar.