Profiler analiza el jitter de la memoria, Memory Analyzer (mat) analiza las pérdidas de memoria (no sé cómo cortarme)

Prólogo: Recientemente revisé sistemáticamente la optimización del rendimiento de Android. Bloguear es tanto aprender como grabar, y espero ayudar a otros estudiantes mientras graban. Recientemente creo que se me ocurrió una serie que no entiendo. "No sé cómo vencerme", "No sé cómo cortarme", "No sé cómo vencerme"

1. Profiler analiza la fluctuación de la memoria

En nuestro proyecto de desarrollo, si no tiene cuidado, a menudo se producirá una fluctuación de la memoria. Y algunas fluctuaciones de la memoria también pueden hacer que nuestro programa se congele o incluso se filtre. A continuación, use el Profiler que viene con Android Studio para analizar la fluctuación de la memoria.


1.1. Simular jitter de memoria y abrir Profiler

Primero cree una sección de código de jitter de memoria en MainActivity:

private Handler mHandler = new Handler() {
    
    
        @Override
        public void handleMessage(@NonNull Message msg) {
    
    
            super.handleMessage(msg);
            //创造内存抖动
            for (int i = 0; i < 100; i++) {
    
    
                String arg[] = new String[100000];
            }
            mHandler.sendEmptyMessageDelayed(0, 30);
        }
    };

Luego haga clic en el botón en el cuadro rojo a continuación para ejecutar el programa


La siguiente figura aparece después de ejecutar,


Mueva el mouse a MEMORIA y haga doble clic para ingresar al análisis de memoria


Si su proyecto ya se está ejecutando, también puede abrirlo a través de Ver -> Ventanas de herramientas -> Profiler


1.2, analizar la fluctuación de la memoria

Haga clic en el botón para activar el código de fluctuación de la memoria, eche un vistazo a nuestra memoria, puede ver que está irregular

[Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo de enlace anti-sanguijuela. Se recomienda guardar la imagen y subirla directamente (img-It94iFlb-1589018239602) (https://user-gold-cdn.xitu.io/2020/5/9 / 171f780686912499? W = 1613 & h = 558 & f = png & s = 124757)]

Haga clic en el registro en el cuadro rojo de arriba, y luego haga clic en detener para analizar una sección de nuestro irregular, como se muestra en la figura:

[Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo de enlace anti-sanguijuela. Se recomienda guardar la imagen y subirla directamente (img-FaU9X4Ny-1589018239603) (https://user-gold-cdn.xitu.io/2020/5/9 / 171f7861f6544a55? W = 1620 & h = 536 & f = png & s = 141052)]

Asignaciones: indica el número de asignaciones actuales
Tamaño superficial: indica el uso de memoria actual

Puede ver que nuestro String [] ocupa la mayor parte. Después de hacer clic izquierdo en String [], todos los String [] aparecerán a la derecha, y luego hacer clic izquierdo en cualquiera, Allocation Call Stack: aparecerá información de la pila de asignación de memoria:

[Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo de enlace anti-sanguijuela. Se recomienda guardar la imagen y subirla directamente (img-qG6fCUWG-1589018239606) (https://user-gold-cdn.xitu.io/2020/5/9 / 171f78b3a26c5377? W = 1619 & h = 688 & f = png & s = 194039)]

Se puede ver claramente que en nuestro código, se debe a handleMessage: 21, MainActivity $ 1 (com.leo.memoryanalyzertest), que causa jitter de memoria. Haga clic con el botón derecho en este elemento y haga clic en Ir a fuente. Puede ir a nuestro código de problema. Así es como nuestro Profiler analiza la fluctuación de la memoria.

[Error en la transferencia de la imagen del enlace externo. Es posible que el sitio de origen tenga un mecanismo de enlace anti-sanguijuela. Se recomienda guardar la imagen y subirla directamente (img-iUvBSwKD-1589018239607) (https://user-gold-cdn.xitu.io/2020/5/9 / 171f78deef594435? W = 597 & h = 79 & f = png & s = 9879)]

1.3. Si usa el método traceView del artículo anterior, es decir, el método CPU Profiler

En primer lugar, especulamos que traceView es una herramienta poderosa para analizar el retraso y, por supuesto, se puede medir aquí. Pero tenga en cuenta que está sesgado hacia situaciones que requieren mucho tiempo. Como se mencionó en el artículo anterior, no lo explicaré aquí. También haga clic en CPU, luego grabar, detener para grabar una sección. Ven a nuestro Top Down como se muestra:

[Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo de enlace anti-sanguijuela. Se recomienda guardar la imagen y subirla directamente (img-6StOqYUE-1589018239608) (https://user-gold-cdn.xitu.io/2020/5/9 / 171f7d30377e0bf7? W = 1616 & h = 432 & f = png & s = 76401)]

Se puede ver que el tiempo que consume tiempo está en MessageQueue, que también está relacionado con nuestro código de jitter de memoria, que se envía cada 30ms. En handleMessage (), también indica que el código está en com.leo.memoryanalyzertest.MainActivity. Se puede encontrar que esta forma de análisis no es obvia.

Nota: Todos conocemos el jitter de memoria, si queremos buscarlo, también debemos buscar bucles o llamadas frecuentes. Entonces, mirándolo de esta manera, podemos confirmar aproximadamente la ubicación del código del problema usando el CPU Profiler.


2. Analizar las pérdidas de memoria con Memory Analyzer

Del mismo modo, primero creamos un código de pérdida de memoria, primero definimos una interfaz

public interface CallBack {
    
    
    void leoFun();
}

Luego crea una lista estática, agrega una instancia de CallBack

public class CallBackManager {
    
    
    public static ArrayList<CallBack> sCallBacks = new ArrayList<>();

    public static void addCallBack(CallBack callBack) {
    
    
        sCallBacks.add(callBack);
    }

    public static void removeCallBack(Callback callback) {
    
    
        sCallBacks.remove(callback);
    }
}

Luego, cree una BitmapActivity para implementar la interfaz CallBack, establezca una imagen grande main_bg y, al mismo tiempo, si la instancia está en sCallBacks estática, de modo que cada vez que se abra BitmapActivity y luego se salga, BitmapActivity no se reciclará.

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bitmap);

        ImageView imageView = findViewById(R.id.image);
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.main_bg);
        imageView.setImageBitmap(bitmap);
        CallBackManager.addCallBack(this);
    }

De esta forma seguimos abriendo esta página y luego la cerramos para ver la situación de la memoria, como se muestra en la figura, podemos ver que la memoria sube directamente:

Cuadro rojo 1: La función es iniciar activamente un gc. El propósito es recuperar algunos reciclables, referencias fantasmas, etc. Evite la interferencia del análisis de memoria
Cuadro rojo 2: Volcado de montón, convierta la asignación de memoria en un archivo hprof. (Tenga en cuenta que este es el archivo hprof del estudio, si necesita usar el Analizador de memoria para analizarlo, debe convertirse en un archivo hprof estándar)

Haga clic con el botón derecho en Exportar para almacenar el archivo en la carpeta.
[Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo de enlace anti-sanguijuela. Se recomienda guardar la imagen y subirla directamente (img-UXAYTrwP-1589018239611) (https://user-gold-cdn.xitu.io/2020/5/9 / 171f804db306f156? W = 406 & h = 202 & f = png & s = 11520)]

Convierta en archivo hprof reconocido por mat, siempre que la línea de comando cmd llegue al archivo hprof-conv.exe que viene con nuestro estudio, ingrese el comando para convertir

hprof-conv ruta del archivo fuente ruta del archivo de salida, generando así nuestro my.hprof


2.1. Cómo utilizar nuestro analizador de memoria

Después de generar el archivo hprof, utilice Memory Analyzer.
La dirección de descarga del sitio web oficial: https://www.eclipse.org/mat/downloads.php , porque no se recomiendan las donaciones. Encontré una versión más confiable, descargue de csdn

Después de la descarga, inicie MemoryAnalyzer.exe. Archivo -> Abrir Heap Dump para abrir nuestro archivo my.hprof como se muestra:

[Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo de enlace anti-sanguijuela. Se recomienda guardar la imagen y subirla directamente (img-VultZtAS-1589018239616) (https://user-gold-cdn.xitu.io/2020/5/9 / 171f88c66a73a658? W = 1672 & h = 866 & f = png & s = 74494)]

Primero introduzca brevemente la información de Memory Analyzer.

2.1.1. Cuadro rojo 1: Información general de OverView

  • Tamaño Tamaño de la memoria
  • Clases: objeto de clase
  • Objetos: el número de Objetos, es decir, el número de instancias
  • Histograma de objetos inalcanzables: objetos que pueden reciclarse y guardarse en la memoria

2.1.2. Cuadro rojo 2: Histograma de histograma

  • Objetos: cuántas instancias de esta clase
  • Montón poco profundo: memoria ocupada por una sola instancia
  • Montón retenido: cuánta memoria ocupan una sola instancia y sus referencias

Podemos usar el histograma para buscar nuestro primer caso de fuga de memoria en Regex. Busque BitmapActivity como se muestra en la figura, puede ver que nuestra BitmapActivity tiene 3 instancias:

Podemos hacer clic derecho en com.leo.me, oryanalyzertest.BitmapActivity -> List objects -> con la referencia entrante (quién me citó), como se muestra en la figura, podemos ver que hay 3 lugares donde se hace referencia a BitmapActivity:

En este punto, hacemos clic con el botón derecho en una instancia y hacemos clic en Path To GC Roots -> con todas las referencias, como se muestra en la figura, busque el archivo con el pequeño sol debajo del archivo, que puede desencadenar el desbordamiento de la memoria. Esto quiere decir que se hace referencia a nuestro sCallBacks, y también se confirma que la colección estática sCallBacks en el CallBackManager en nuestro código de fuga de memoria lo ha agregado.


2.1.3. Cuadro rojo 3: el árbol dominador muestra la memoria y la proporción de cada instancia

Puede ver que la gran cabeza aquí es el mapa de bits.

[Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo de enlace anti-sanguijuelas. Se recomienda guardar la imagen y subirla directamente (img-Z2MXW4F3-1589018239623) (https://user-gold-cdn.xitu.io/2020/5/9 / 171f869560338e9c? W = 1448 & h = 209 & f = png & s = 32203)]

De manera similar, podemos hacer clic con el botón derecho en una instancia Path To GC Roots -> con todas las referencias como se muestra en la figura, y también podemos ver que se hace referencia a nuestro sCallBacks:

[Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo de enlace anti-sanguijuela. Se recomienda guardar la imagen y subirla directamente (img-YXLRYn0a-1589018239624) (https://user-gold-cdn.xitu.io/2020/5/9 / 171f86d44c60df13? W = 716 & h = 387 & f = png & s = 43407)]


2.1.4. Cuadro rojo 4: OQL, similar a nuestra situación de memoria en la búsqueda de bases de datos

Después de escribir el comando, haga clic en el signo de exclamación rojo para ejecutar, como se muestra en la figura

[Error en la transferencia de la imagen del enlace externo. Es posible que el sitio de origen tenga un mecanismo de enlace anti-sanguijuela. Se recomienda guardar la imagen y subirla directamente (img-HplpQ0dW-1589018239625) (https://user-gold-cdn.xitu.io/2020/5/9 / 171f870f6aa8ce57? W = 670 & h = 350 & f = png & s = 25925)]


2.1.5. Cuadro rojo 5: descripción general del hilo, que muestra el estado del hilo


2.1.6. Cuadro rojo 6: Principales consumidores (énfasis), que muestra directamente la gran cantidad de memoria en nuestra memoria

Demuestre que nuestra memoria ocupa una cantidad relativamente grande de memoria, puede ver que este lugar está ocupado por 3 mapas de bits grandes. Intuitivo para el análisis


2.1.7. Cuadro rojo 7: Sospechosos de fuga (énfasis), dar directamente el análisis, analizar las posibles fugas de memoria en nuestro código

[Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo de enlace anti-sanguijuela. Se recomienda guardar la imagen y subirla directamente (img-0JPPBQZT-1589018239628) (https://user-gold-cdn.xitu.io/2020/5/9 / 171f879c46453d10? W = 832 & h = 680 & f = png & s = 56188)]

Aquí comencé BitmapActivity 3 veces, y también me dio 3 análisis. Haga clic en detalles. Mirando los detalles, también solucioné directamente el problema en sCallBacks:

[Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo de enlace anti-sanguijuelas. Se recomienda guardar la imagen y subirla directamente (img-64JHGAkL-1589018239629) (https://user-gold-cdn.xitu.io/2020/5/9 / 171f87de82e08ede? W = 873 & h = 445 & f = png & s = 55325)]


Mi cuenta oficial

Publicaré algunos artículos prácticos y vernáculos. También he estado buscando las técnicas de entrevista más ventajosas. Los compañeros de clase que tienen ideas pueden estar juntos

Supongo que te gusta

Origin blog.csdn.net/leol_2/article/details/106024932
Recomendado
Clasificación