Android Optimización del rendimiento Optimización de casos (3) de fluctuación de fase y pérdidas de memoria

prefacio

Esta serie de artículos:
1, a modo de explicación fácil de comprender, explicar el valor práctico de una tecnología
2, un seguimiento de fuentes detallado por escrito, captura en el origen, la estructura de clases de dibujo, trata de explicar los principios del proceso de descubrimiento en detalle
3,. Github puede ejecutar el proyecto de demostración, pero me han proporcionado el código, proporcionar más ideas, mejores ideas, por favor CV adecuadas
precauciones durante la operación 4, terminando una serie de principios en el proceso de exploración de una cisterna, o en la demo
5, con gif la figura, la mayoría de los resultados operativos intuitivos muestran demostración

Si cree que los detalles son demasiado delgadas, puede omitir para ver la conclusión.
capacidad limitada, si la descripción que se encuentra inadecuada, la bienvenida a los mensajes de la crítica.

Este artículo conectado a uno; APP Caton optimización


contorno del cuerpo

  • los conocimientos de gestión de memoria JVM
  • La detección y el procesamiento de la memoria fluctuación
  • Y una detección de fugas de memoria de procesamiento

texto

los conocimientos de gestión de memoria JVM

  • LMK (LowMemoryKill) mecanismo
    androide inferior será cuando el sistema no tiene memoria, de acuerdo con ciertas reglas para matar algunos procesos para satisfacer las necesidades de memoria de otros procesos. Que consumen memoria, que es un indicador de nivel, por lo que la optimización del consumo de memoria de la aplicación, puede reducir efectivamente la probabilidad de morir sistema de aplicación.
  • GC STW mecanismo de
    GC, proceso de recolección de basura, hilos GC cuando se realiza una tarea, habrá una STW (parar el mundo) mecanismo, que pondrá todo se suspenden los otros hilos. Si el GC llama con mucha frecuencia, que dará lugar a que el hilo principal no es suave, dando al usuario la sensación es 卡顿.
  • fluctuación de memoria causa frecuente OOM
    fluctuación de memoria demasiado a menudo, con frecuencia resulta en un gran número de objetos creados y destruidos, no puede producir grandes cantidades de espacio de memoria contigua, en este momento si existe la necesidad de aplicar la memoria de objeto grande, es posible aplicar fallar, lo que lleva OOM内存溢出.
  • pérdida de memoria palabra para explicar
    el ciclo de vida del objeto mantener el ciclo de vida de una fuerte referencia al objeto, el ciclo de vida del descubrimiento cuando los objetos tienen que ser recuperados 不能para ser reciclados, considerado como fugas
  • recuperación Alcanzabilidad análisis GC
  • hilo GC puede determinar si se recupera un objeto, de acuerdo con algoritmo de análisis de alcanzabilidad para calcular GcRoot, a partir de GcRootla búsqueda hacia abajo, la GcRoottotalidad de objeto no está directamente relacionada con la recogida de basura.
  • referencias débiles fuertes virtuales de cuatro
    fuertes e imaginario sin decir. La fuerte más común, no existe un tratamiento especial aparecen referencias fuertes (incluyendo clase interna anónima llevará a cabo una fuerte referencia a la clase externa). No se discute referencia fantasma inútil,.
    referencias suaves, así como para definir un cierto uso, pero no tiene un objeto, utilice SoftRefrence<T>modificado, en la memoria tensa, después de GC se recogió usando un SoftRefrence<T>sistema de destino modificado si hay suficiente memoria disponible, la asociación no tendría una referencia suave se recicla. Si insuficiente, la recuperación de software de la referencia de objeto asociado.
    (Referencias débiles WeakRefrence<T>), se recuperarán más débil que el número de referencia suave, siempre y cuando el objeto GC gatillo asociado con referencias débiles.
    注意,使用软和弱引用,要判定关联对象是否为空。

La detección y el procesamiento de la memoria fluctuación

Utilizamos s de desarrollo, que generalmente se ejecuta la aplicación, por lo general apuntar EjecutarAplicación, pero no hay otra opción, que es, después de profileApp, aplicación en funcionamiento, verá la ventana de abajo como el perfil

Después de hacer clic, como se verá a continuación el perfil, la figura mostrará la red, la memoria y el uso de la CPU

Si la memoria de la figura fluctuación muy claro, como ECG, tales como:

Esto demuestra que hay un recuerdo muy claro de fluctuación en la urgente necesidad de tratamiento:

Después de hacer clic en el área de gráficos de la memoria, se puede ver cambios detallados en la memoria, y la asignación de memoria:

Aquí es un pozo :

Si nos fijamos en el dibujo para suavizar la memoria de tendencias, y no aparece en la simulación completa de la figura fluctuación de manera exagerada, no hay fluctuación de memoria no es así? No lo es. Debido a que nuestro GC, en el caso de la memoria no estará disponible en la memoria de recuperación, si la aplicación ocupan memoria ha sido relativamente pequeña, no toque la GC valor crítico, entonces no aparecerá 断崖式下跌. Así que esto fue observado no sacudir la memoria, cómo hacerlo?

Solución
en los teléfonos Android 8.0 o menos, habrá un botón de grabación en la posición más baja (si es 8,0 o más, puede directamente arrastrar y soltar a la interceptación de un registro de memoria):

Haga clic en él, después de un tiempo, y luego pulsa: se puede encontrar una forma a continuación:

Esta forma representa, que se graban los objetos creados dentro de este período de tiempo, haga clic en la segunda columna Allocations, el número de especie creada, averigüe para crear el mayor número de objetos:

Entonces, después de clic cadena ocupa el primer lugar, verá a la derecha:

A continuación, haga clic en uno de ellos, verá una nueva ventana:

Hasta ahora, para encontrar 创建对象el 元凶orden esto como una pista, encontrar sus propias clases y métodos nombre del paquete, determinar nuestro propio código irrazonablemente crear el objeto.

Más adelante, con sus respectivos códigos de hacer la optimización del negocio, y un propósito en mente: no deje que el código para hacer las cosas adicionales . Si llamamos el sistema API llevado a la creación irrazonablemente gran número de objetos, entonces debemos considerar por qué esto es así que el sistema API para crear objetos, no hay otra manera de evitarlo, de la capa de negocio de código para el uso racional de este API, no es y luego considerar otro sistema o costumbre API API.

Hicimos una optimización después, y luego ejecutar una aplicación de perfil, y luego repetir el proceso. Y así sucesivamente, hasta que el movimiento de la memoria de alcanzar el estado deseado.

resumen

Optimizar la fluctuación de memoria, el núcleo es evitar que el frecuente crear objetos. ejemplo negativo común es: ciclo de crear un objeto, el objeto de la API para crear un gran número de llamadas. Los principales medios de optimizado, es la reutilización de objetos, medios comunes es: la agrupación de objetos, tales como la piscina lista única controlador de mensajes, piscinas de mapa de bits de planeo.


Y una detección de fugas de memoria de procesamiento

caso clásico : Manejo de handlerlas pérdidas de memoria causadas por los métodos de tareas asíncronas

  • Eliminar todas las tareas en la Actividad OnDestroy
    @Override
    protected void onDestroy() {
        super.onDestroy();
        handler.removeCallbacksAndMessages(null);//移除所有任务
    }

  • Manera usando clases internas estáticas + Actividad referencias débiles
    MyHandler handler = new MyHandler(this);
    private static class MyHandler extends Handler {
        WeakReference<Activity> activityWeakReference;

        MyHandler(Activity activity) {
            activityWeakReference = new WeakReference<>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            //在执行任务的时候,判断弱引用所关联的对象是否为空,能在对象已经被回收的情况下,不去执行不必要的任务
            switch (msg.what) {
              case 1:
                if (activityWeakReference.get() != null) {
                    //TODO
                }
            }
        }
    }

El uso de herramientas

Aún así profileApp, primero profilevisto cambios en la memoria.

  • Q: ¿Cómo determinar las pérdidas de memoria?
    A: Una pérdida de memoria es el esfuerzo bien, no se observa totalmente, sólo en virtud de los cambios en el perfil de memoria para especular .
    Por ejemplo, después de abrir la memoria aplicación disparado, hasta el máximo de memoria que puede ser utilizado fuera de la aplicación, aplicación se bloquea ,, este es el más evidente.
    Como otro ejemplo, que en repetidas ocasiones se abren y cierran interfaz de uno, encontrar un recuerdo de una línea estable ( 内存稳定之后,内存占用值) con cada uno de la apertura y cierre, están mejorando, lo que demuestra que hay una fuga en esta interfaz, el objeto no se puede recuperar.

En la sección anterior utilizando profile los más se aprende a crear objetos y reclamar lo que causó la fluctuación de memoria, sin embargo, implica fugas, sólo a través perfil 不能saber 哪个类持有了希望被回收的对象的强引用.
Aquí es necesario el uso de una herramienta adicional, y su nombre es:  Eclipse Mat (propios Baidu)

Para volver a la primera profile,

Tap, tap entonces, la interfaz pasará automáticamente:

Haga clic en el botón Guardar para guardar el archivo localmente;

entonces:

Pero el archivo no se puede abrir directamente sobre la alfombra.

Para localizar el directorio SDK hprof-conv.exe:

Use comandos cmd, convertir el archivo, el comando es: hprof-conv [源文件名] [目标文件名]
como  hprof-conv 1.hprof 2.hprof un retorno de carro

El resultado 2.hprofuso de herramientas abiertas acaba de descargar Mat:

Hay muchos indicadores, pero verifique que no haya fugas de memoria, sólo tenemos que centrarnos en el botón Histograma:

Esta figura una lista de todos los objetos que volcar la memoria de este periodo, incluyendo la capa marco, incluyendo nuestro propio código crea objetos.

caso de simulación

Simulé un caso clásico, que es el anteriormente mencionados Handlercables tarea de retardo Activityno pueden ser puestos en libertad, el código básico es el siguiente:

Yo uso una forma muy común para crear un handlerobjeto y lo utilizan para realizar tareas de un retraso, pero el tiempo de retardo de la tarea de retardo es Integermáxima, es decir, mucho después de que se ejecutará la tarea. Después de eso, en varias ocasiones fuera de éste Activity, y luego siga la forma anterior dumppor un tiempo  hprof, después de  hprof-conv la conversión, a continuación Matabierto:
Los resultados son como sigue:

Llené información de filtro: SecondActivity Enter:

En nuestra salida final SecondActivitydespués, la memoria aún conserva 18un objeto inútil.

No es que somos 18 fugas de ella?

No necesariamente.

Se ha mencionado anteriormente, sólo referencias fuertes irrazonables, dará lugar a pérdidas de memoria, así que tenemos que excluir débil fantasma de referencia de acuerdo con el método anterior.
A continuación podemos ver la siguiente interfaz, la información se puede ampliar para dar todo de desplegado:

Aprenden Handler源码compañeros deben mirar a ver para entender, handlercausa una pérdida de memoria, porque no son excesivamente fuerte cadena de referencias,
la figura de arriba se puede ver, en última instancia objeto de devolución de llamada tiene el  SecondActivityobjeto.

callback El tiempo de retardo de la tarea es demasiado largo, sin embargo, no se ha realizado, por lo que las referencias fuertes no le dará liberado mientras callbacksostiene la Activityllevó Activityno puede ser puesto en libertad.

Cómo optimizar pérdida de memoria

Acabamos de ver el uso irracional Handler provoca una pérdida de memoria, así que si usted onDestroyquita todas las tareas:

Realizar las mismas tareas, volcado hacia abajo hprof la alfombra:

Después de la activación de la GC, SecondActivityel número se convierte en 0, pérdidas de memoria resueltos.

Por supuesto, hay otro enfoque, las clases internas estáticas + débil.

PD: las clases internas estáticas es evitar que la clase interna tiene referencias a la clase externa, una referencia débil para cuando se dispara GC, la recuperación de objetos perdidos WeakRefrence.

public class SecondActivity extends AppCompatActivity {
    Handler handler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        handler.postDelayed(runnable, Integer.MAX_VALUE);//依然是那个延时很久的任务
    }

    Runnable runnable = new MyRunnable(this);

    private static class MyRunnable implements Runnable {// 静态内部类
        WeakReference<Activity> activityWeakReference;//弱引用

        MyRunnable(Activity activity) {
            activityWeakReference = new WeakReference<>(activity);
        }

        @Override
        public void run() {

        }
    }
}

Pero entonces descartado, un no.

consejos

Los pasos anteriores, mientras sea posible, pero si hay muchas páginas necesitan para solucionar la fuga, a continuación, vamos un punto para abrir una página cerrada, todo el proceso será muy largo incómodo. De hecho, hay una solución.

Volver antes de que el histograma:

El uso es: si quieres una operación, un hprof antes y después de cada operación de volcado usted nombró antes y después, y luego se convierte con hprof-CONV aproximadamente, y se convierten en before_ after_, abrir los dos archivos al mismo tiempo con la colchoneta eclipse, a continuación, interruptor a la after_.hprof, haga clic en el botón de arriba imagen:

Se le permitirá elegir el archivo que desea comparar, haga clic before_, SecondActivity después se filtró a:

Esta realización puede filtrarse antes de la elaboración, la región de código puede filtrarse antes de la investigación. Simplificar nuestro trabajo de optimización.

epílogo

Las pérdidas de memoria y la optimización de la fluctuación Jvm implica una gran cantidad de conocimientos, además de los puntos que se enumeran anteriormente, hay una gran cantidad de pequeños detalles. Para hacer la optimización de memoria JVM necesita una sólida base de conocimientos.

Anterior: optimización APP Caton

 

Publicado 56 artículos originales · ganado elogios 1 · vistas 2918

Supongo que te gusta

Origin blog.csdn.net/chuhe1989/article/details/104478266
Recomendado
Clasificación