English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Análisis superficial de la sobrecarga de memoria en Android y métodos de prevención

Este ejemplo describe los métodos de gestión de memoria y prevención de desbordamiento en programación Android. Compartimos con todos para referencia, como se detalla a continuación:

 La máquina virtual de Android se basa en el registro Dalvik, y el tamaño máximo de la pila generalmente es16M. Pero Android se escribe en Java, por lo que en gran medida, el mecanismo de memoria de Android es equivalente al mecanismo de memoria de Java, y en el momento de la desarrollo inicial, los problemas de restricciones de memoria pueden traernos problemas graves como desbordamientos de memoria. Cuando no utilizamos cierta memoria, debemos evitar en la medida de lo posible que se guarden estados necesarios en otras plataformas o mientras se ejecutan otros programas, lo que puede causar problemas de memoria en procesos muertos. Por lo tanto, es mejor liberar estos estados cuando se cierre el programa o se guarden los estados, de esta manera se puede mejorar la fluidez del sistema en ejecución.

La memoria de Android se manifiesta principalmente en:

1En la plataforma Android, mantener referencias a recursos a largo plazo puede causar que cierta memoria no se pueda liberar, lo que lleva a muchos problemas de fugas de memoria. Por ejemplo: Contexto (en el texto siguiente, se mencionan Activity como Contexto), en algunas situaciones en las que necesitas mantener el estado de tu primera clase y transmitir ese estado a otros objetos de clase, debes liberar primero el objeto de clase receptor antes de eliminar la primera clase. Es importante destacar que: en el mecanismo de memoria de Java o Android, el nodo de la cima debe garantizarse que no sea llamado por otros objetos antes de que pueda ser reciclado y liberado por el sistema GC. Veamos un fragmento de código:

@Override
protected void onCreate(Bundle state) {
   super.onCreate(state);
   TextView label = new TextView(this);
   label.setText("Leaks are bad");
   setContentView(label);
}

El significado de este código es que hemos cargado una instancia de TextView en el Activity (Contexto) que estamos ejecutando. Por lo tanto, mediante el mecanismo de reciclaje de GC, sabemos que para liberar el Contexto, es necesario liberar primero los objetos que lo hacen referencia. Si no lo hacen, al intentar liberar el Contexto, descubrirás que hay una gran cantidad de desbordamientos de memoria. Por lo tanto, en caso de que accidentalmente se produzca un desbordamiento de memoria, es algo muy fácil de hacer. Al guardar algunos objetos, también puede causar fugas de memoria. El ejemplo más simple es el bitmap (Bitmap), por ejemplo: cuando se rota la pantalla, se destruye el estado actual del Activity que se mantiene y se solicita la creación de un nuevo Activity, hasta que se guarda el estado del nuevo Activity. Veamos otro fragmento de código:

private static Drawable sBackground;
@Override
protected void onCreate(Bundle state) {
super.onCreate(state);
TextView label = new TextView(this);
label.setText("Las fugas de memoria son malas");
if (sBackground == null) {
   sBackground = getDrawable(R.drawable.large_bitmap);
}
label.setBackgroundDrawable(sBackground);
setContentView(label);
}

Este código es muy rápido, pero también es erróneo. La fuga de memoria es fácilmente detectable en la dirección de la transferencia de pantalla. Aunque podemos descubrir que no hay una instancia de Context guardada explícitamente, cuando conectamos un dibujo a una vista, el Drawable lo hace de vuelta al View, lo que significa que en el código anterior, en realidad hemos referenciado esta Activity al dibujar TextView en la actividad. La situación de enlace puede manifestarse como: Drawable->TextView->Context.

Por lo tanto, cuando quieres liberar el Context, realmente aún se mantiene en la memoria y no se libera.

cómo evitar esta situaciónPrincipalmente, los hilos son los más propensos a errores. No subestimes a los hilos, en Android los hilos son los más propensos a causar fugas de memoria. La razón principal de que los hilos causen fugas de memoria es que su ciclo de vida no es controlable. A continuación, hay un fragmento de código:

public class MyTest extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    new MyThread().start();
  }
  private class MyThread extends Thread{
    @Override
    public void run() {
      super.run();
      //hacer algo
    }
  }
}

El código es simple, pero en Android se presentan nuevos problemas, cuando cambiamos la pantalla de vista (apaisado o en vertical), se crea de nuevo la Activity en apaisado o en vertical. Imaginamos que la Activity creada anteriormente se reciclará, pero ¿qué sucede en realidad? El mecanismo de Java no te dará la misma sensación, ya que antes de liberar la Activity, porque la función run no ha finalizado, MyThread no se ha destruido, por lo tanto, la Activity que lo referencia (Mytest) también puede no haber sido destruida, lo que lleva a problemas de fugas de memoria.

Algunas personas prefieren usar AsyncTask proporcionado por Android, pero de hecho, los problemas de AsyncTask son más graves. El problema de fuga de memoria de Thread solo ocurre cuando la función run no termina, sin embargo, el mecanismo de implementación interno de AsyncTask utiliza ThreadPoolExecutor, y la vida útil del objeto Thread generado por esta clase es incierta y no puede ser controlada por la aplicación. Por lo tanto, si AsyncTask se utiliza como clase interna de Activity, es más probable que aparezca el problema de fuga de memoria.

Las formas de mejora de problemas de hilos主要包括:

① Cambie la clase interna de hilo a una clase interna estática.
② Trate de usar referencias débiles para guardar Context en el programa.

2¡Qué malo es bitmap...!

Bitmap es un objeto muy malo, para un objeto de memoria, si el objeto ocupa demasiado espacio en memoria, cuando excede los límites de memoria del sistema, el problema de fuga de memoria es muy obvio...
La solución principal para bitmap es evitar que se almacene en la memoria o reducir la tasa de muestreo. En muchos casos, debido a que la resolución de las imágenes es muy alta, y para el tamaño de la pantalla del teléfono, no es necesario que las imágenes tengan una alta proporción de píxeles para cargar, podemos reducir primero la tasa de muestreo de la imagen y luego realizar las operaciones UI originales.

Si no necesitamos guardar la referencia del objeto bitmap, también podemos usar referencias suaves como sustituto. Hay muchos ejemplos de código específicos en google.

En resumen, para evitar fugas de memoria, es necesario seguir los siguientes puntos principales:

Primero: No guarde referencias a Context a largo plazo (si necesita referenciar Context, asegúrese de que el ciclo de vida del objeto de referencia sea consistente con él mismo).

Segundo: Si necesita usar Context, trate de usar ApplicationContext en su lugar, ya que el ciclo de vida de ApplicationContext es más largo y no causará problemas de fugas de memoria en situaciones de referencia.

Tercero: Evite usar variables estáticas en su Activity cuando no controle el ciclo de vida de los objetos. Trate de usar WeakReference en lugar de una estática.

Cuarto: El recolector de basura no garantiza que pueda reciclar la memoria de manera precisa, por lo que al usar el contenido necesario, es necesario liberar los objetos no necesarios en el ciclo de vida principal. Trate de liberar los objetos a los que nos referimos en onDestroy cuando finalice la vida del Activity, por ejemplo: cursor.close().

En realidad, podemos usar menos código en muchos aspectos para completar el programa. Por ejemplo: podemos usar más de9imágenes patch, etc. Hay muchos detalles donde podemos descubrir y excavar más problemas de memoria. Si podemos lograr que C/C++En cuanto al principio de 'quien crea, quien libera' de los programas, nuestra comprensión de la memoria no es inferior a la de Java o al mecanismo de GC de Android en sí, y una mejor control de la memoria puede hacer que nuestro teléfono funcione más suavemente.

Los lectores interesados en más contenido relacionado con Android pueden ver la sección especial de este sitio: 'Resumen de técnicas de memoria y caché en desarrollo de Android', 'Tutorial de inicio y avanzado en desarrollo de Android', 'Resumen de técnicas de depuración y solución de problemas comunes en desarrollo de Android', 'Resumen de técnicas de operaciones multimedia en Android (audio, video, grabación, etc.)', 'Resumen de uso de componentes básicos en Android', 'Resumen de técnicas de View en Android', 'Resumen de técnicas de layout en Android' y 'Resumen de uso de controles en Android'.

Espero que lo descrito en este artículo pueda ayudar a todos en el diseño de programas Android.

Declaración: El contenido de este artículo se ha obtenido de la red, pertenece a los propietarios originales, el contenido ha sido contribuido y subido por usuarios de Internet, este sitio no posee los derechos de propiedad, no ha sido editado por humanos y no asume ninguna responsabilidad legal relacionada. Si encuentra contenido sospechoso de infracción de derechos de autor, le invitamos a enviar un correo electrónico a notice#w.3En caso de encontrar contenido infractor, por favor envíe un correo electrónico a notice#w para denunciar, y proporcione evidencia relevante. Una vez verificada, este sitio eliminará inmediatamente el contenido sospechoso de infracción.

Te gustará