Red de conocimiento informático - Computadora portátil - Optimización de la memoria de Android

Optimización de la memoria de Android

Práctica de optimización de la memoria de Android

1. Modelo y distribución de la memoria

Sabemos que la mayoría de las aplicaciones de Android se desarrollan utilizando el lenguaje Java, lo que requiere que comprendamos el modelo de memoria de Java. Las aplicaciones de Android se desarrollan en base a Dalvik VM o ART VM, por lo que también se debe comprender la distribución de memoria de estas máquinas virtuales.

La figura anterior muestra la distribución de memoria de las máquinas virtuales Java comunes:

Área de método: almacena principalmente información de clases, constantes, variables estáticas cargadas por la máquina virtual y códigos compilados a tiempo. por el compilador, etc. datos. Esta parte de la optimización de la memoria considera principalmente no cargar una gran cantidad de bibliotecas de terceros innecesarias. La reducción de esta parte de la memoria se debe principalmente al reciclaje de grupos constantes y la descarga de clases (condiciones de descarga de clases: sin referencias, el cargador de clases puede descargar)

Montón: casi todos los objetos se generan en Esta área pertenece al área que disfrutan los subprocesos, por lo que debe prestar más atención a la seguridad de los subprocesos múltiples al escribir código. El tamaño de esta área de memoria cambia principalmente debido a la creación y el reciclaje de objetos. Por ejemplo: si se crea y recicla una gran cantidad de objetos en un corto período de tiempo, puede causar fluctuaciones en la memoria si no se reciclan todos los objetos. El tiempo después de su creación, puede causar pérdidas de memoria. Las pérdidas de memoria graves pueden provocar gc frecuentes, lo que provoca un retraso en la interfaz.

Pila de máquina virtual: esta área describe el modelo de memoria de ejecución del método Java. Lo que a menudo llamamos pila de método es almacenar el marco de la pila del método en la pila de la máquina virtual. thread., su ciclo de vida es el ciclo de vida del hilo. Es decir, cada subproceso tendrá, de forma predeterminada, el tamaño de la pila de subprocesos de un subproceso es 1M, lo que no incluye el tamaño de otros objetos generados en el método. En esta área, todo lo que podemos controlar es la cantidad de subprocesos, especialmente si el programa no usa un grupo de subprocesos o usa múltiples bibliotecas de terceros con grupos de subprocesos.

Pila de métodos nativos: es muy similar a la pila de máquinas virtuales. La máquina virtual la utiliza para ejecutar métodos nativos, por lo que debe prestar atención a las mismas cosas que la pila de máquinas virtuales, especialmente. si usa un tercero,

Contador de programa: un registrador del número de líneas de código de bytes de la máquina virtual ejecutadas por el hilo actual. Ocupa una pequeña cantidad de memoria, por lo que puede ignorarlo.

2. Límite de memoria

Android se basa en el sistema Linux, los procesos de Android se dividen en dos tipos:

1: implementación de C/C++, el proceso de Linux que lo hace no incluye la instancia de dalvik, todos los archivos de programa en el directorio /system/bin/ se ejecutan. Existe en forma de proceso nativo

Proceso 2.java: un proceso de Linux que crea una instancia de la máquina virtual Dalvik. instancia. La función principal de entrada de este proceso es la función java. El proceso de host de la instancia de la máquina virtual Dalvik es un proceso de Linux creado por la llamada al sistema fork (), por lo que cada proceso Java de Android es en realidad un proceso de Linux, y solo este proceso es un proceso de Linux. Un proceso de Linux solo tiene una instancia más de máquina virtual Dalvik en el proceso.

Sabemos que el sistema operativo tiene restricciones en la memoria del proceso y el sistema operativo también tiene restricciones en el tamaño de la memoria del montón del proceso. La propia máquina virtual Dalvik. El tamaño límite se puede ver usando: adb shell getprop | grep dalvik.vm.heapgrowthlimit, para aumentar el tamaño del montón en la máquina virtual Dalvik

A menudo decimos que el tamaño del montón en realidad tiene dos partes, uno es el montón de Java y el otro es el montón local. El montón de Java son principalmente los bits de los objetos java. C El espacio de memoria solicitado por / C ++ está en el montón local, y también hay algunos objetos en el montón local. .

En el montón nativo, hay algunos objetos que deben usarse junto con el montón nativo y el montón de Java, como los mapas de bits. Los mapas de bits se dividen en objetos de mapa de bits y los valores de píxeles se almacenan en ellos. Montón de Java, y los píxeles son Los valores se almacenan en la memoria en diferentes ubicaciones en diferentes versiones, API 11 - API 25 se almacenan en el montón de Java, otras versiones se almacenan en el montón nativo y otras versiones se almacenan en el montón nativo. montón. Otras versiones se almacenan en el montón local;

3. Pérdidas de memoria

Pérdidas de memoria comunes:

1. Referencias estáticas (código propio y código de terceros) )

2. Referencias dentro de la colección

3. Mensajes del controlador no borrados

4. Clases internas no estáticas que contienen aplicaciones internas externas

5. Clases internas anónimas/no estáticas y subprocesos asincrónicos

Método de verificación:

Aquí uso Leakcanary. Generalmente, las pérdidas de memoria simples se pueden verificar directamente en el enlace Leakcanary. , que no se puede ver, uso MAT para analizar la información de la memoria actual;

El significado de los indicadores detallados en la imagen de arriba se puede encontrar aquí, que ocupa principalmente un área relativamente grande:

asignado: el número de objetos Java asignados dentro de la aplicación. A partir del valor actual, se puede ver que el programa puede crear demasiados objetos, como objetos de cadena.

Nativo: objetos asignados desde C. o Memoria de código C++. La entrada y salida frecuente de páginas relacionadas muestra que el tamaño del montón local no está disminuyendo, lo que indica una pérdida de memoria en el nivel c/c++

Código: su aplicación utiliza código y recursos como el código de bytes dex, optimización o compilación de código dex, bibliotecas .so y fuentes). Las optimizaciones que puede realizar en esta área incluyen eliminar bibliotecas so innecesarias, usar bibliotecas so para carga diferida y eliminar código inútil (importaciones, métodos y clases)

4. Prácticas de optimización

Después de comprender la distribución de la memoria y las fugas relacionadas con Android, el siguiente paso es optimizar la memoria según su propio negocio, de la siguiente manera:

1. Primero, resuelva el problema de que el programa ocupa mucho memoria. El problema de pérdida de memoria del módulo empresarial. Si no está familiarizado con el uso de MAT, puede leer este artículo

2. Elimine el código redundante y las referencias en el programa. detección de pelusa y luego coopere con ShrinkResources para eliminar recursos no válidos

3. Optimice las imágenes, asegúrese de que se coloquen en carpetas razonables, cargue los tamaños de imagen adecuados según el tamaño de vista y luego optimice la memoria empresarial. Optimice la creación de objetos, como cadenas, utilizando grupos de objetos, etc.