Optimización del rendimiento de Android: resumen del análisis de optimización de la memoria

1. Concepto de optimización de la memoria

1.1 ¿Por qué necesitamos optimizar la memoria?

La optimización de la memoria siempre ha sido un punto muy importante pero carece de atención. Como uno de los recursos más importantes para la ejecución de un programa, la memoria debe asignarse y reciclarse de manera razonable durante la operación. El uso irrazonable de la memoria puede incluso hacer que la aplicación del usuario se ejecute. Stuttering, ANR y la pantalla negra puede incluso causar fallas OOM (falta de memoria) en las aplicaciones del usuario. Si lo sigue con atención, puede encontrar que el lugar donde ocurre el problema de la memoria es solo una manifestación, no la causa profunda, porque el problema de la memoria es relativamente complejo, es un proceso de compresión gradual y resulta que está en El código donde tienes el problema está explotado, por lo que los desarrolladores deben prestar más atención a los problemas de memoria de la aplicación.

1.2 Manifestaciones de problemas de memoria.

  • Fluctuación de la memoria: GC irregular y frecuente que provoca retrasos

  • Pérdida de memoria: la memoria disponible disminuye gradualmente, GC frecuente

  • Desbordamiento de memoria: OOM, excepción del programa

2. Herramientas de análisis de memoria de uso común.

Para solucionar problemas de memoria debemos contar con potentes herramientas de análisis de memoria que nos permitan localizar problemas de memoria de forma más rápida y cómoda. Las principales herramientas de análisis de memoria actuales incluyen principalmente LeakCanary, Memory Profiler y MAT.

2.1 FugaCanario

LeakCanary es un marco de monitoreo de fugas de memoria de código abierto de Square. LeakCanary monitoreará y registrará las pérdidas de memoria que ocurran mientras la aplicación se está ejecutando.

 Análisis de seguimiento de pérdida de memoria de LeakCanary, que analiza principalmente el seguimiento de Fuga: NO a Fuga: SÍ, puede encontrar que TextView tiene una pérdida de memoria porque contiene el contexto de la Actividad destruida.

Para un análisis de seguimiento más específico, puede ver el documento oficial Reparar una pérdida de memoria.

Aunque usar LeakCanary es muy conveniente, también tiene ciertas desventajas:

  • La referencia directa al LeakCanary utilizado por las dependencias generalmente se usa para la depuración fuera de línea y debe cerrarse cuando la aplicación se lanza en línea.

  • La depuración de aplicaciones a veces provoca retrasos

Por lo tanto, generalmente usar LeakCanary es solo una forma sencilla de localizar pérdidas de memoria. Sin embargo, si necesita una mejor optimización de la memoria, como localizar la fluctuación de la memoria, optimización de mapas de bits, etc., aún necesita otras herramientas de análisis. Las principales de uso común son Memoria Perfilador y MAT.

2.2 Tamaño nativo, tamaño poco profundo, tamaño retenido, profundidad

Al describir Memory Profiler y MAT más adelante, a menudo aparecerán varios indicadores más importantes: tamaño superficial y tamaño retenido. El tamaño y la profundidad nativos también se proporcionan en Memory Profiler.

Después de obtener un volcado de montón, Memory Profiler mostrará una lista de clases. Para cada clase, la columna Asignaciones muestra el número de instancias. A la derecha están el tamaño nativo, el tamaño poco profundo y el tamaño retenido:

Usamos la siguiente figura para representar el estado de la memoria de la aplicación registrado por un determinado volcado de montón. Preste atención al nodo rojo. En este ejemplo, el objeto representado por este nodo se refiere al objeto Nativo de nuestro proyecto; esta situación es menos común, pero después de Android 8.0, tal situación puede ocurrir cuando se usa Bitmap, porque la información de Bitmap Pixel se almacenará en la memoria nativa para reducir la presión de la memoria JVM.

Comencemos con Shallow Size. Esta columna de datos es en realidad muy simple: es el tamaño de la memoria consumida por el propio objeto.

La profundidad es el camino más corto desde GC Root hasta esta instancia. Los números en la figura son la profundidad (Profundidad) de cada objeto.

Cuanto más cerca esté un objeto de GC Root, es más probable que esté conectado a GC Root a través de múltiples rutas y es más probable que se guarde durante la recolección de basura.

Tomando el nodo rojo como ejemplo, si se destruye alguna referencia del lado izquierdo, el nodo rojo se volverá inaccesible y será recolectado como basura. Para el nodo azul de la derecha, si desea que se recoja la basura, debe destruir los caminos de la izquierda y la derecha.

Vale la pena señalar que si ve una instancia con una profundidad de 1, significa que GC Root hace referencia directa a ella, lo que también significa que nunca se reciclará automáticamente.

A continuación se muestra una actividad de ejemplo que implementa la interfaz LocationListener. La parte resaltada del código, requestLocationUpdates(), utilizará la instancia de actividad actual para registrar el administrador de ubicación. Si olvida cerrar sesión, esta actividad se filtrará. Permanecerá en la memoria para siempre, porque el administrador de ubicación es una raíz de GC y siempre existirá:

Puedes ver esto en Memory Profiler. Haga clic en una instancia y Memory Profiler abrirá un panel que muestra quién hace referencia a la instancia:

Podemos ver que el mListener en el administrador de ubicación hace referencia a esta Actividad. Puede ir un paso más allá y navegar a la vista de referencia del montón a través del panel Referencias, lo que le permitirá verificar que la cadena de referencia es la que espera y también le ayudará a comprender si hay fugas en su código y dónde.

2.3 Perfilador de memoria

Memory Profiler es una herramienta de análisis de memoria integrada en Android Studio adecuada para ver las condiciones de la memoria en tiempo real.

2.3.1 Descripción de la interfaz del Perfilador de memoria

Documentación oficial: utilice Memory Profiler para ver el montón de Java y la asignación de memoria

2.3.2 Memory Profiler para encontrar la fluctuación de la memoria

Encontrar la fluctuación de la memoria es relativamente simple: el programa en ejecución aparecerá en Memory Profiler a medida que la memoria fluctúa hacia arriba y hacia abajo en un corto período de tiempo, lo que activa el reciclaje de GC con frecuencia.

Lugares comunes donde ocurre la fluctuación de la memoria:

  • Personalice onMeasure(), onLayout(), onDraw() de View para crear objetos directamente con new

  • Listas como onBindViewHolder() de RecyclerView crean directamente objetos con nuevos

  • Creando objetos en código con bucles

Utilice un caso simple para simular la destrucción de la memoria:

publicclassMainActivityextendsAppCompatActivity {
​@SuppressWarnings("HandlerLeak")privateHandler mHandler = newHandler() {@OverridepublicvoidhandleMessage(Message msg) {// 模拟内存抖动for (int i = 0; i < 100; i++) {String[] args = newString[100000];}
​mHandler.sendEmptyMessageDelayed(0, 30);}};
​@OverrideprotectedvoidonCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);
​findViewById(R.id.button).setOnClickListener(newView.OnClickListener() {@OverridepublicvoidonClick(View v) {mHandler.sendEmptyMessage(0);}});}
}
复制代码

El caso es muy simple, es decir, con frecuencia se crean objetos cuando se hace clic en el botón. Es posible que ejecutar el programa anterior en una máquina real no cause fluctuaciones irregulares en la memoria, pero habrá un reciclaje de GC muy frecuente, como se muestra en la siguiente figura:

Entonces, ¿cómo deberíamos localizar específicamente dónde se produce la fluctuación de la memoria?

Siga los pasos anteriores:

  • Posición ①: Cuando el programa se esté ejecutando, haga clic en el botón Grabar para registrar el estado de la memoria y luego haga clic en Detener para detener la grabación. Se mostrará la imagen de arriba.

  • Posición ②: Podemos hacer clic en Asignaciones para ver la cantidad de objetos asignados en orden descendente de grande a pequeño o en orden ascendente de pequeño a grande. Generalmente, elegiremos ver la mayor cantidad de objetos en orden descendente de grande a pequeño. El mayor número de objetos en la figura anterior es el objeto String.

  • Posición ③: seleccione un objeto de cadena en la vista de instancia y se mostrará la pila de llamadas de asignación a continuación, que mostrará la ubicación de la pila de llamadas de este objeto.

  • Posición 4: desde la pila de llamadas de asignación, podemos ver que el objeto String se crea en handleMessage() en la línea 18 de MainActivity, localizando así la ubicación de la fluctuación de la memoria.

Hay algunos consejos para la operación anterior:

  • Antes de operar en la posición ①, para eliminar la interferencia, la memoria cambiada generalmente se realizará GC manualmente antes de grabar; en dispositivos superiores a Android 8.0, puede arrastrar el Perfilador de memoria en tiempo real para seleccionar el rango de fluctuación de la memoria para ver.

  • Posición ② El ejemplo anterior es para ver directamente Organizar por clase, pero en proyectos reales, más personas elegirán Organizar por paquete para ver las clases bajo su propio nombre de paquete de proyecto.

2.3.3 Memory Profiler para encontrar pérdidas de memoria

Como se mencionó anteriormente, la manifestación de las pérdidas de memoria es que se producirá fluctuación de la memoria, porque cuando ocurre una pérdida de memoria, la memoria disponible continúa disminuyendo. Cuando el sistema necesita memoria, cuando la memoria es insuficiente, se producirá GC, por lo que se producirá fluctuación de la memoria.

Cuando se produce una pérdida de memoria, Memory Profiler mostrará una tendencia ascendente de memoria similar a una escalera y la memoria no disminuye:

La pérdida de memoria en la imagen de arriba es bastante obvia. Cuando ocurre una pérdida de memoria en el desarrollo del proyecto real, puede que no sea particularmente obvia. Llevará mucho tiempo ejecutarlo y descubrir que la memoria está aumentando lentamente. En este momento, se necesita un montón de volcado para ayudar a localizarlo.

A continuación, usaremos el caso de la pérdida de memoria del Handler para explicar brevemente cómo usar Memory Profiler para analizar las pérdidas de memoria.

public classHandlerLeakActivityextendsAppCompatActivity{private static finalStringTAG = HandlerLeakActivity.class.getSimpleName();
​privateHandler handler = newHandler() {@Overridepublic void handleMessage(Message msg) {if (msg.what == 0) {Log.i(TAG, "handler receive msg");}}};
​@Overrideprotected void onCreate(@NullableBundle savedInstanceState) {super.onCreate(savedInstanceState);handler.sendEmptyMessageDelayed(0, 10 * 1000);}
}
复制代码

El código anterior es muy simple: después de iniciar la aplicación, cada vez que ingresa a HandlerLeakActivity, use Handler para retrasar el envío de mensajes durante 10 segundos, salga de la interfaz en 10 segundos y repita la operación.

1. Repita la operación que puede causar pérdidas de memoria varias veces y el montón del Memory Profiler volcará el archivo hprof (se recomienda eliminar la interferencia del GC antes de la operación)

2. Vea el archivo de volcado del montón hprof en Memory Profiler:

Se puede encontrar que después de la GC manual, las asignaciones muestran 5 HandlerLeakActivities, y aún se muestran múltiples instancias de actividad en la vista de instancia de volcado de montón, lo que indica que se han producido pérdidas de memoria. Se puede hacer clic en la ubicación específica de la pérdida de memoria en el objeto de clase de instancia filtrada en Vista de instancia. Ver, la Referencia debajo de la Vista de instancia mostrará la cadena de referencia específica.

En la nueva versión de Memory Profiler, se proporciona la casilla de verificación Actividad/Fragmentos Fugas. Al seleccionarla, se puede encontrar directamente la ubicación de posibles pérdidas de memoria:

2.4 TAPETE

2.4.1 Introducción a MAT

  • Potente herramienta de análisis Java Heap para encontrar pérdidas de memoria y uso de memoria

  • Genere informes generales, analice problemas y más

  • Uso en profundidad fuera de línea

Dirección de descarga del sitio web oficial: www.eclipse.org/mat/downloa..., ¿Hay palabras que le resulten familiares en esta dirección? Bueno, así es, MAT es un complemento de Eclipse, porque muchas personas ahora usan IDEA en el proceso de desarrollo O Android Studio, por lo que si no desea descargar Eclipse, puede descargar la versión independiente de MAT. Después de la descompresión, contiene un archivo ejecutable MemoryAnalyzer.exe y puede usarlo haciendo clic en él.

Muchas veces necesitamos usar esta herramienta junto con la capacidad de volcado de montón de Android Studio. Sin embargo, debe tenerse en cuenta que el archivo hprof generado después de AS3.0 no es un archivo hprof estándar. Debe usar el comando para convertirlo. : hprof-conv Después de convertir la ruta del archivo original, la ruta del archivo

2.4.2 Introducción al uso de MAT

①.Descripción general: información general

Principales consumidores

  • Los objetos que ocupan más memoria se muestran mediante gráficos. Esta columna es más útil para reducir el uso de memoria.

  • Objetos más grandes: información relativamente detallada

Sospechosos de fugas

  • Verifique rápidamente puntos sospechosos de pérdidas de memoria

②, Histograma: Histograma

  • Nombre de clase: busca específicamente una determinada clase

  • Objetos: cuántas instancias de una clase específica hay

  • Montón poco profundo: ¿Cuánta memoria ocupa una sola instancia?

  • Montón retenido: ¿cuánta memoria ocupan estos objetos en total en esta cadena de referencia?

Agrupar por paquete: muestra objetos de clase en forma de nombres de paquetes

Listar objetos

  • con referencias salientes: ¿A qué clases se hace referencia por sí sola?

  • con referencias entrantes: a qué clases se hace referencia en sí

③、dominator_tree

  • Árbol de dominación para cada objeto.

  • porcentaje: porcentaje de todos los objetos

Haga clic derecho en el elemento y también tendrá objetos de Lista. ¿Cuál es la diferencia entre este y el Histograma? Las principales diferencias son los dos puntos siguientes:

  • Histograma: análisis de perspectiva basado en clases

  • dominator_tree: análisis de perspectiva basado en ejemplos

④. OQL: lenguaje de consulta de objetos, similar a recuperar contenido de una base de datos

⑤, thread_overview: visualización detallada de la información del hilo, puede ver cuántos hilos existen actualmente en la memoria

3. Solución práctica para la fluctuación de la memoria

3.1 Introducción a la fluctuación de la memoria

  • Definición: la asignación y el reciclaje frecuentes de memoria provocan inestabilidad de la memoria

  • Rendimiento: GC frecuente, curva de memoria irregular

  • Peligros: Provocando retraso y, en casos severos, OOM.

3.2 La fluctuación de la memoria causa OOM

  • Creación frecuente de objetos, lo que resulta en memoria insuficiente y fragmentación (discontinuidad)

  • No se pueden asignar segmentos de memoria discontinuos, lo que genera OOM

3.3 Análisis práctico

En esta parte, simularé una fluctuación de la memoria, analizaré la situación de la memoria a través del Profiler y localizaré el código de fluctuación de la memoria específico.

Primero, creemos un archivo de diseño Activity_memory.xml, que contiene un botón para activar la parte del código que simula la fluctuación de la memoria:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical" android:layout_width="match_parent"android:layout_height="match_parent"><Buttonandroid:id="@+id/btn_memory"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="模拟内存抖动"/>
</LinearLayout>
复制代码

Luego defina una página MemoryShakeActivity, cargue el diseño ahora y defina un controlador en la página. Cuando se hace clic en el botón para simular la agitación de la memoria, ejecutamos regularmente el código para simular la agitación en handleMessage. Todo el código es fácil de entender. :

/*** 说明:模拟内存抖动页面*/publicclassMemoryShakeActivityextendsAppCompatActivityimplementsView.OnClickListener {@SuppressLint("HandlerLeak")privatestaticHandler mHandler = newHandler(){@OverridepublicvoidhandleMessage(@NonNull Message msg) {super.handleMessage(msg);//模拟内存抖动的场景,每隔10毫秒执行一次,循环执行100次,每次通过new分配大内存for (int i=0;i<100;i++){String[] obj = newString[100000];}mHandler.sendEmptyMessageDelayed(0,10);}};@OverrideprotectedvoidonCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_memory);findViewById(R.id.btn_memory).setOnClickListener(this);}@OverridepublicvoidonClick(View view) {if (view.getId() == R.id.btn_memory){mHandler.sendEmptyMessage(0);}}@OverrideprotectedvoidonDestroy() {super.onDestroy();mHandler.removeCallbacksAndMessages(null);}
}
复制代码

Luego comencé a correr y tomé dos fotografías para que todos las vieran: la primera imagen es antes de que se ejecute el código para simular la fluctuación y la segunda imagen es después de la ejecución:

En las dos imágenes de arriba, puede ver claramente que la primera memoria es relativamente estable y la segunda imagen de memoria tiene una apariencia irregular, y de repente hay GC frecuentes. ¿Ves muchos botes de basura pequeños debajo? En este momento, puedes Haga un juicio preliminar de que debería ser Aparece el fenómeno de la fluctuación de la memoria, porque está más acorde con sus características, luego arrastre una cierta distancia en el panel y nos mostrará la asignación de memoria durante este período:

Primero haga doble clic en Asignaciones y luego organice esta columna en orden de mayor a menor, y luego encontrará que hay tantas matrices de cadenas y también ocupa el tamaño de memoria más alto (he marcado los puntos dignos de atención con rectángulos), deberíamos bloquear este objetivo en este momento. ¿Por qué hay tantas matrices de tipo String? Probablemente haya un problema aquí. Luego solucione el problema que está causando este problema. Es muy simple hacer clic en la línea Cadena [] y hacer clic en cualquier línea en el panel Vista de instancia a la derecha. La información de la pila correspondiente aparecerá en el panel Pila de llamadas de asignación a continuación. La información también se enumera arriba. Para qué línea de qué clase, haga clic con el botón derecho en saltar a la fuente para saltar a la ubicación del código fuente especificada. De esta manera, podemos encontrar la ubicación donde ocurre la fluctuación de la memoria y luego podemos analizar el código y realizar las modificaciones correspondientes.

Resumen del proceso:

  1. Solución de problemas preliminar con Memory Profiler;

  1. Utilice Memory Profiler o CPU Profiler para solucionar problemas de código

Consejos para resolver la fluctuación de la memoria: busque bucles o llamadas frecuentes

4. Resolución de pérdida de memoria real

4.1 Introducción a las pérdidas de memoria

Definición: Ya no hay objetos útiles en la memoria.

Rendimiento: la memoria tiembla, la memoria disponible disminuye gradualmente

Peligros: memoria insuficiente, GC frecuente, OOM

4.2 Análisis práctico

Aquí todavía usamos código para simular verdaderamente un escenario de pérdida de memoria. Para los programas de aplicaciones generales, el mayor problema suele ser el mapa de bits, porque consume más memoria y será más obvio usarlo para simular. Bueno, primero veamos el archivo de diseño Activity_memoryleak.xml, que contiene un control ImageView:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><ImageViewandroid:id="@+id/iv_memoryleak"android:layout_width="50dp"android:layout_height="50dp" />
</LinearLayout>
复制代码

Luego definimos una interfaz de devolución de llamada que simula el procesamiento de ciertos servicios y una clase de Administrador que administra de manera uniforme estas interfaces de devolución de llamada:

//模拟回调处理某些业务场景publicinterfaceCallBack {voiddpOperate();
}//统一管理CallbackpublicclassCallBackManager {publicstatic ArrayList<CallBack> sCallBacks = new ArrayList<>();publicstaticvoidaddCallBack(CallBack callBack) {sCallBacks.add(callBack);}publicstaticvoidremoveCallBack(CallBack callBack) {sCallBacks.remove(callBack);}
}
复制代码

Luego configure Bitmap en nuestra página de pérdida de memoria simulada y configure la escucha de devolución de llamada:

/*** 说明:模拟内存泄露页面*/
public classMemoryLeakActivityextendsAppCompatActivityimplementsCallBack{@Overrideprotected void onCreate(@NullableBundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_memoryleak);ImageView imageView = findViewById(R.id.iv_memoryleak);Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.big_bg);imageView.setImageBitmap(bitmap);CallBackManager.addCallBack(this);}@Overridepublic void dpOperate() {}
}
复制代码

Bien, nuestro código ha sido escrito. Ahora ejecútelo y luego abra y cierre esta página varias veces seguidas para ver si este código causará una pérdida de memoria.

Esta es una imagen de la memoria que capturé con Profiler. Puedes ver que toda la memoria tiene una pequeña fluctuación en algunos lugares después de cambiar de página repetidamente. Sin embargo, la memoria general aumenta en forma de escalera y la memoria disponible disminuye gradualmente. Básicamente se puede concluir que hay una pérdida de memoria en esta interfaz. Aunque la herramienta Profiler puede ayudarnos inicialmente a determinar que se ha producido una pérdida de memoria, no puede determinar dónde se produjo la pérdida de memoria, lo que significa que todavía no sabemos dónde modificar el código, por lo que debemos utilizar la potente herramienta Java Heap. en este momento., Ven e invita a MAT a jugar.

Primero, debe hacer clic en el botón Volcar montón de Java en Profiler, usar la función de volcado de montón para convertirlo en un archivo y luego hacer clic en el botón Guardar para guardar el archivo en un directorio local. Por ejemplo, yo lo guardo como el archivo Memoryleak.hprof en la unidad H y luego use hprof El comando -conv lo convierte en un archivo hprof estándar, el nombre convertido aquí es: Memoryleak_transed.hprof, como se muestra a continuación:

Luego abra la herramienta MAT e importe el archivo convertido que acaba de generar:

Haga clic en Histograma para ver todos los objetos supervivientes en la memoria, y luego podemos ingresar contenido en el Nombre de clase para buscar el objeto que queremos encontrar:

Luego puede ver la información específica del objeto, así como el número y el tamaño de la memoria ocupada. Descubrí que en realidad hay 6 objetos MemoryLeakActivity en la memoria:

Luego haga clic derecho en Listar objetos---->con referencias entrantes para encontrar todas las referencias sólidas que conducen a él:

Luego haga clic derecho en Ruta a GC Roots----->con todas las referencias, cuente todas las referencias y calcule la ruta entre este objeto y GCRoot:

Mirando los resultados, finalmente llegamos a sCallBacks, y hay un pequeño círculo en la esquina inferior izquierda. Esta es la ubicación que realmente estamos buscando, lo que significa que el objeto sCallBacks de la clase CallBackManager hace referencia a MemoryLeakActivity:

De acuerdo con los resultados encontrados anteriormente, vaya al código para encontrar sCallBacks de CallBackManager para ver qué lo causó aquí.

publicstaticArrayList<CallBack> sCallBacks = new ArrayList<>();
复制代码

La variable estática sCallBacks hace referencia a MemoryLeakActivity. Dado que el ciclo de vida de la variable modificada por la palabra clave estática es tan largo como el ciclo de vida completo de la aplicación, cuando se cierra la página MemoryLeakActivity, debemos liberar la relación de referencia de la variable. De lo contrario, se producirá el problema de pérdida de memoria anterior. Entonces resolver este problema es muy simple, agrega las siguientes líneas de código:

@OverrideprotectedvoidonDestroy() {super.onDestroy();CallBackManager.removeCallBack(this);
}
复制代码

Resumen del proceso:

  1. Observación inicial utilizando Memory Profiler (la memoria disponible disminuye gradualmente);

  1. Combinado con confirmación de código a través de Memory Analyzer

5. Solución de monitoreo de memoria en línea

El mayor problema de la memoria en línea son las pérdidas de memoria. La fluctuación y el desbordamiento de la memoria generalmente están relacionados con la incapacidad de liberar memoria causada por las pérdidas de memoria. Si se pueden resolver las pérdidas de memoria, los problemas de la memoria en línea se reducirán mucho. El monitoreo de la memoria en línea es bastante difícil porque no podemos usar estas herramientas fuera de línea para descubrir y analizar problemas de manera intuitiva.

5.1 Solución convencional

①.Establecer escena volcado en línea

Por ejemplo, si su aplicación ha ocupado un porcentaje mayor de la memoria máxima disponible de una sola aplicación, como 80%, pase: Debug.dumpHprofData(); esta línea de código puede convertir la información de la memoria actual en un archivo local.

Todo el proceso es el siguiente: Más del 80% de la memoria -> Volcado de memoria -> Devolver el archivo (tenga en cuenta que el archivo puede ser grande, manténgalo en estado wifi y devuélvalo) -> Análisis manual MAT

Resumir:

  • El archivo de volcado es demasiado grande y está directamente relacionado con la cantidad de objetos y se puede recortar.

  • Alta tasa de errores de carga y análisis difícil

② Utilice LeakCanary en línea

  • LeakCanary lo pone en línea

  • Puntos de sospecha de fugas preestablecidos

  • Devolución de datos filtrada encontrada

Resumir:

  • No apto para todas las situaciones, las dudas deben estar preestablecidas, lo que limita la exhaustividad.

  • El análisis requiere mucho tiempo y es propenso a OOM (en la práctica, se descubre que el proceso de análisis de LeakCanary es lento y es muy probable que se produzca OOM durante el proceso de análisis)

5.2 Personalización de LeakCanary

  • Puntos de sospecha preestablecidos: "Encontrar automáticamente puntos de sospecha (sospeche de quien tiene una gran huella de memoria, la probabilidad de problemas con objetos de memoria grandes es mayor)

  • Análisis lento de enlaces filtrados (analiza cada objeto del objeto preestablecido) -> Analiza objetos con un tamaño de retención grande (reduce su carga de trabajo de análisis y aumenta la velocidad de análisis)

  • Analizar OOM (asigna todos los archivos generados por la pila de memoria a la memoria, lo que ocupa más memoria) -> Recorte de objetos, no todos cargados en la memoria

5.3 Solución completa para monitoreo en línea

  • Memoria en espera, memoria del módulo clave, tasa OOM

  • Tiempos de GC generales y del módulo clave y tiempo de GC

  • Análisis automatizado de pérdida de memoria LeakCanary mejorado

6. Habilidades de optimización de la memoria.

Dirección general de optimización:

  • pérdida de memoria

  • paliza de memoria

  • mapa de bits

Detalles de optimización:

  • Atributo LargeHeap (aunque es un poco fraudulento, aún debes aplicarlo al sistema)

  • onTrimMemory, onLowMemory (las devoluciones de llamada con poca memoria proporcionadas por el sistema pueden manejar cierta lógica de acuerdo con diferentes niveles de devolución de llamada)

  • Utilice colecciones optimizadas: SparseArray

  • Utilice SharedPreference con precaución (cargue en la memoria una vez)

  • Utilice bibliotecas externas con precaución (intente elegir bibliotecas externas que hayan sido verificadas a gran escala)

  • La arquitectura empresarial está razonablemente diseñada (los datos cargados son los que puede usar, no se desperdicia memoria cargando datos inútiles)

 

Supongo que te gusta

Origin blog.csdn.net/qq_25462179/article/details/132737973
Recomendado
Clasificación