Pérdidas de memoria en Android

Una fuga de memoria es básicamente una falla en la liberación de objetos no utilizados de la memoria. Como desarrollador, no es necesario pensar en la asignación de memoria, la desasignación de memoria y la recolección de elementos no utilizados. Todos estos son el proceso automático que el recolector de elementos no utilizados realiza por sí mismo, pero la situación se vuelve difícil para el recolector de elementos no utilizados cuando el usuario hace referencia al objeto, que ya no está en uso, pero como ese objeto está siendo referenciado por otro objeto, El recolector de basura siente que el objeto no utilizado está siendo utilizado por otro objeto y, debido a esto, el recolector de basura no libera la memoria de ese objeto, por lo que la memoria del montón disponible disminuye, lo que provoca escasez de memoria y pérdida de memoria. El objeto no liberado se llama básicamente fugas.

Las fugas de memoria son las causas comunes de los bloqueos de aplicaciones en las aplicaciones de Android. Todo desarrollador debe saber cómo evitar fugas de memoria y cuáles son las circunstancias que pueden provocar fugas de memoria en las aplicaciones de Android. Cuando los recursos de RAM no se liberan cuando ya no se necesitan y si esto se hace varias veces, la parte de la memoria que el sistema operativo ha asignado a esa aplicación en particular puede exceder el límite superior y el sistema puede cerrar la aplicación causando la falla. aplicación para bloquearse. Mantener las referencias del objeto y los recursos que ya no se necesitan es la causa principal de las fugas de memoria en las aplicaciones de Android.  Como se sabe, la memoria para el objeto en particular se asigna dentro del montón y el objeto apunta a ciertos recursos utilizando alguna referencia de objeto. Pero cuando se completa el trabajo, las referencias de objetos deben liberarse. Pero cuando no se hace, el espacio de almacenamiento dinámico aumenta continuamente y el resto de la aplicación tiene que ejecutarse en el espacio de almacenamiento dinámico que queda y, en última instancia, hay muchas posibilidades de que se produzcan fugas de memoria en la aplicación. Por lo tanto, se puede decir que las fugas de memoria son un término que se usa cuando nuestra aplicación se queda sin memoria porque algún objeto que no se usa pero aún está siendo señalado por las referencias y ocupando continuamente el espacio del montón, lo que finalmente conduce a una escasez. de espacio para los otros componentes de la aplicación y, por lo tanto, eventualmente provoca que la aplicación se bloquee.

Nota: Es necesario recordar que cada vez que hay escasez de espacio en el montón y el sistema necesita asignar espacio para algunos objetos nuevos, se llama al recolector de elementos no utilizados en intervalos frecuentes, lo que provoca la ralentización de la aplicación o, en algún momento, el la aplicación puede bloquearse.

Causas de las fugas de memoria y sus soluciones

1. Uso de vistas estáticas

No se deben usar vistas estáticas mientras se desarrolla la aplicación, ya que las vistas estáticas nunca se destruyen.

2. Usar contexto estático

Uno nunca debe usar el Contexto como estático, porque ese contexto estará disponible a lo largo de la vida de la aplicación y no estará restringido a la actividad particular.

clase pública MainActivity extiende AppCompatActivity {

     // esto no se debe hacer

     Botón de botón estático privado;

}

3. Usar la abstracción de código con frecuencia 

Los desarrolladores a menudo aprovechan la propiedad de abstracción porque proporciona el mantenimiento del código y la flexibilidad en el código, pero el uso de la abstracción puede costarle un poco al desarrollador, ya que al usar la abstracción se necesita escribir más código, más código significa más tiempo para ejecutar el espacio y más RAM. Entonces, siempre que uno pueda evitar la abstracción en el código, es código, ya que puede generar menos pérdidas de memoria.

4. Oyentes no registrados

Cuando el desarrollador utiliza cualquier tipo de oyente en el código de su aplicación, no debe olvidarse de cancelar el registro del oyente.

5. Receptores no registrados

Muchas veces el desarrollador necesita dar de alta al receptor de emisión local en una actividad. Sin embargo, si el desarrollador no cancela el registro del receptor de transmisión, existe una gran posibilidad de que nuestra aplicación provoque un problema de fuga de memoria, ya que el receptor tendrá una fuerte referencia a la actividad. Entonces, incluso si la actividad no sirve, evitará que el recolector de elementos no utilizados recopile la actividad para la recolección de elementos no utilizados, lo que en última instancia provocará la pérdida de memoria.

Kotlin

// sample kotlin program for broadcast receiver 
import android.app.Activity
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle
import com.example.myapplication.R
  
class LocalBroadcastReceiverActivity : Activity() {
  
    private var localBroadcastReceiver: BroadcastReceiver? = null
  
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
  
    private fun registerBroadCastReceiver() {
        localBroadcastReceiver = object : BroadcastReceiver() {
            override fun onReceive(context: Context, intent: Intent) {
                // Write your code here
            }
        }
        registerReceiver(localBroadcastReceiver, IntentFilter("android.net.conn.CONNECTIVITY_CHANGE"))
    }
  
    override fun onStart() {
        super.onStart()
        // registering the broadcast receiver
        registerBroadCastReceiver()
    }
  
    override fun onStop() {
         super.onStop()
          
         // Broadcast receiver holds the implicit reference of Activity.
           // Therefore even if activity is destroy,
         // garbage collector will not be able to remove its instance.
         if (localBroadcastReceiver != null) {
            unregisterReceiver(localBroadcastReceiver)
        }
    }
}

6. Referencia de clase interna

Los desarrolladores de Android suelen utilizar una clase interna dentro de su código. Sin embargo, la clase no estática mantendrá la referencia implícita de la clase principal, lo que puede causar el problema de pérdida de memoria. Por lo tanto, puede haber dos soluciones que se pueden proponer para resolver este problema:

  • Uno puede hacer que la clase interna sea estática.
  • Si se quiere pasar la referencia de la clase interna no estática, se puede pasar usando una referencia débil.

Herramientas para detectar fugas de memoria

Como se sabe que cuando algo no se ve es muy difícil arreglarlo, al igual que la fuga de memoria, no se ve, entonces es muy difícil arreglarlo . Pero hay algunas herramientas que nos ayudan a detectar las fugas de memoria en la aplicación de Android y nos ayudan a solucionarlo. Veamos algunas de las herramientas más populares:

1. Canario de fugas

Leak Canary es una biblioteca de detección de memoria en Android. Es desarrollado por una empresa de vasos cuadrados. Esta biblioteca tiene una capacidad única para disminuir la fuga de memoria y ayudar a los desarrolladores a obtener menos «MemoryOutOfError». El control de fugas incluso nos ayuda a notificar dónde está ocurriendo realmente la fuga. Para usar Leak-Canary, agregue la siguiente dependencia en build.gradle(app level file) .

dependencias {

 // debugImplementation porque LeakCanary solo debe ejecutarse en compilaciones de depuración.

 debugImplementation ‘com.squareup.leakcanary:leakcanary-android:2.4’

}

Una vez que se instala el control de fugas, detecta e informa automáticamente las fugas de memoria en 4 pasos:

  • Detección de objetos retenidos.
  • Volcar el montón.
  • Analizando el montón.
  • Categorización de fugas.

Si uno quiere profundizar más y aprender cómo filtrar el informe canario de fugas de memoria, puede consultar la documentación oficial de la fuga canaria .

2. Perfilador de Android

Básicamente es una herramienta que ayuda a realizar un seguimiento del uso de la memoria de cada aplicación en Android. Reemplazó a Android Monitor en la versión de Android 3.0 y superior. Android Profiler es compatible con Android 5.0 (API nivel 21) y superior. Android Profiler detecta el rendimiento de la aplicación en tiempo real en los parámetros como:

  • Batería
  • Memoria (en MB)
  • Uso de CPU (en %)
  • Tasa de red (tasa de carga y recepción)

Para abrir el generador de perfiles de Android dentro del proyecto de Android en Android Studio, realice los siguientes pasos: Elija Ver > Ventanas de herramientas > Perfilador > Seleccionar destino de implementación y elija el dispositivo. El rendimiento de la aplicación aparecerá como se muestra en la siguiente imagen: 

Image Showing App Usage Data Using  Andorid Profiler in various respects

Para saber más sobre cómo funciona el generador de perfiles de Android, consulte la documentación oficial del generador de perfiles de Android .

Publicación traducida automáticamente

Artículo escrito por lavishgarg26 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *