Recolector de basura en Android

He visto muchas respuestas de Android que sugieren llamar al recolector de basura en algunas situaciones.

¿Es una buena práctica solicitar el recolector de basura en Android antes de realizar una operación de memoria hambrienta? Si no, ¿debería llamarlo solo si recibo un error de OutOfMemory ?

¿Hay otras cosas que debería usar antes de recurrir al recolector de basura?

Para versiones anteriores a 3.0 Honeycomb : Sí, llame a System.gc() .

Traté de crear mapas de bits, pero siempre obtenía “VM de error de memoria”. Pero, cuando llamé a System.gc() primero, estaba bien.

Al crear mapas de bits, Android a menudo falla con errores de falta de memoria y no intenta recolectar basura primero . Por lo tanto, llame a System.gc() y tenga suficiente memoria para crear Bitmaps.

Si creo objetos, creo que se llamará automáticamente a System.gc si es necesario, pero no para crear mapas de bits. Simplemente falla.

Entonces recomiendo llamar manualmente a System.gc() antes de crear bitmaps.

En términos generales, en presencia de un recolector de basura, nunca es una buena práctica llamar manualmente al GC. Un GC se organiza en torno a algoritmos heurísticos que funcionan mejor cuando se los deja en sus propios dispositivos. Llamar al GC manualmente a menudo disminuye el rendimiento.

Ocasionalmente , en algunas situaciones relativamente raras, uno puede encontrar que un GC particular se equivoca, y una llamada manual al GC puede mejorar las cosas, en cuanto al rendimiento. Esto se debe a que no es posible implementar un GC “perfecto” que gestionará la memoria de forma óptima en todos los casos. Tales situaciones son difíciles de predecir y dependen de muchos detalles sutiles de implementación. La “buena práctica” es dejar que el GC funcione solo; una llamada manual al CG es la excepción, que debe contemplarse solo después de que un problema de rendimiento real haya sido debidamente observado.

La falta de memoria en la aplicación de Android es muy común si no manejamos el bitmap correctamente. La solución para el problema sería

 if(imageBitmap != null) { imageBitmap.recycle(); imageBitmap = null; } System.gc(); BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 3; imageBitmap = BitmapFactory.decodeFile(URI, options); Bitmap scaledBitmap = Bitmap.createScaledBitmap(imageBitmap, 200, 200, true); imageView.setImageBitmap(scaledBitmap); 

En el código anterior, acaba de intentar reciclar el bitmap que le permitirá liberar el espacio de memoria utilizado, por lo que la memoria insuficiente puede no suceder. He intentado que funcionó para mí.

Si aún enfrenta el problema, también puede agregar estas líneas

 BitmapFactory.Options options = new BitmapFactory.Options(); options.inTempStorage = new byte[16*1024]; options.inPurgeable = true; 

para más información, mire este enlace

http://voices.yahoo.com/android-virtual-machine-vm-out-memory-error-7342266.html


NOTA: Debido a la “pausa” momentánea causada por la realización de gc, no se recomienda hacer esto antes de cada asignación de bitmap.

El diseño óptimo es:

  1. Libere todos los mapas de bits que ya no sean necesarios , mediante el código if / recycle / null que se muestra. (Haga un método para ayudar con eso).

  2. System.gc();

  3. Asigna los nuevos mapas de bits.

Si obtiene un OutOfMemoryError, entonces es demasiado tarde para llamar al recolector de basura …

Aquí hay una cita del desarrollador de Android:

La mayoría de las veces, la recolección de basura se produce debido a toneladas de objetos pequeños y de corta vida, y algunos recolectores de basura, como los basureros generacionales, pueden optimizar la recolección de estos objetos para que la aplicación no se interrumpa con demasiada frecuencia. Desafortunadamente, el recolector de elementos no utilizados de Android no puede realizar tales optimizaciones y la creación de objetos efímeros en las rutas de códigos de rendimiento crítico es, por lo tanto, muy costosa para su aplicación.

Entonces, según entiendo, no hay necesidad urgente de llamar al gc. Es mejor gastar más esfuerzo para evitar la creación innecesaria de objetos (como la creación de objetos dentro de los bucles)

Mi aplicación administra muchas imágenes y murió con OutOfMemoryError. Esto me ayudó. En el Manifest.xml Agregar

  

Parece que System.gc() no funciona en Art Android 6.0.1 Nexus 5x, entonces uso Runtime.getRuntime().gc(); en lugar.

En general, no debe llamar a GC explícitamente con System.gc (). Incluso hay la conferencia IO ( http://www.youtube.com/watch?v=_CruQY55HOk ) en la que explican qué significa el registro de pausas de GC y en el que también declaran que nunca deben llamar a System.gc () porque Dalvik lo sabe mejor. que tú cuando hacerlo

Por otro lado, como se menciona en las respuestas anteriores, el proceso de GC en Android (como todo lo demás) a veces no funciona. Esto significa que los algoritmos GC de Dalvik no están a la par con las JVM Hotspot o JRockit y es posible que en ocasiones provoquen errores. Una de esas ocasiones es cuando se asignan objetos de bitmap. Esto es complicado porque usa memoria Heap y Non Heap y porque una instancia suelta de un objeto bitmap en un dispositivo con memoria limitada es suficiente para darle una excepción OutOfMemory. Por lo tanto, llamarlo después de que no necesite más este bitmap es generalmente sugerido por muchos desarrolladores e incluso algunas personas lo consideran una buena práctica.

Una mejor práctica es usar .recycle () en un bitmap, ya que es para lo que está hecho este método, ya que marca la memoria nativa del bitmap como segura de eliminar. Tenga en cuenta que esto es muy dependiente de la versión, lo que significa que, en general, se requerirá en versiones anteriores de Android (Pre 3.0, creo), pero no será necesario en las posteriores. Tampoco le dolerá mucho usarlo en versiones más nuevas de éter (simplemente no lo hagas en un bucle o algo así). El nuevo tiempo de ejecución de ART ha cambiado mucho aquí porque introdujeron una “partición” de Heap especial para objetos grandes, pero creo que no va a doler mucho hacer esto con ART ether.

También una nota muy importante sobre System.gc (). Este método no es un comando al que Dalvik (o JVM) están obligados a responder. Considéralo más como decir a la máquina virtual “¿Podrías hacer una recolección de basura si no es una molestia”.

La mejor forma de evitar OOM durante la creación de Bitmap,

http://developer.android.com/training/displaying-bitmaps/index.html

No es necesario llamar al recolector de basura después de un OutOfMemoryError .

Es Javadoc claramente dice:

Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector.

Entonces, el recolector de basura ya intentó liberar memoria antes de generar el error pero no tuvo éxito.

Diría que no, porque el desarrollador documenta el estado de uso de la RAM :


GC_EXPLICIT

Un GC explícito, como cuando llamas a gc () (que debes evitar llamar y en su lugar confías en que el GC se ejecute cuando sea necesario).

He resaltado la parte relevante en negrita.

Echa un vistazo a la serie de YouTube, Android Performance Patterns : te mostrará consejos sobre cómo administrar el uso de la memoria de tu aplicación (como usar SparseArray s de Android y SparseArray s en lugar de HashMap s).

Nota rápida para los desarrolladores de Xamarin .

Si desea llamar a System.gc() en aplicaciones Xamarin.Android, debe llamar a Java.Lang.JavaSystem.Gc()