Práctica de monitoreo de fiebre de Android

1. Antecedentes

Creo que ahora que los terminales móviles están muy de moda todo el mundo tendrá más o menos ansiedad por la batería y habrá tenido la mala experiencia de que el móvil se caliente. El problema de calentamiento es un indicador que existe desde hace mucho tiempo y en múltiples escenarios, e involucra muchas influencias, como la capa de aplicación del lado del terminal, el sistema ROM del fabricante del teléfono móvil y el entorno externo. Cómo medir eficazmente los escenarios de calentamiento, localizar los sitios de calentamiento y atribuir los problemas de calentamiento se han convertido en tres desafíos principales en el monitoreo del calentamiento de la capa de aplicación final. Este artículo utiliza algunas prácticas de monitoreo existentes en el lado Android de Dewu. No puede salirse sin entrar en el escenario de cálculo del consumo de energía. Se centra primero en el escenario de calefacción en sí, con la esperanza de brindarle alguna referencia.

2. Definición de fiebre

La temperatura es el indicador más intuitivo que puede reflejar el problema de calefacción. Actualmente, en el lado de Android, utilizamos la temperatura corporal por encima de 37° como línea divisoria, y cada 3° hacia arriba como intervalo de temperatura de calefacción. La temperatura límite superior del La subdivisión del intervalo es 49°, que se divide en 37-40, 40-43, 43-46, 46-49, 49+ cinco niveles.

Utilizando la temperatura del teléfono móvil y el uso de la CPU como primer y segundo factor para determinar si el usuario tiene fiebre, se obtienen otros parámetros para respaldar la escena de la fiebre.

Los indicadores específicos son los siguientes:

Temperatura del teléfono móvil, uso de CPU, uso de GPU;

pila de hilos;

Frecuencia de uso del servicio del sistema;

Dispositivo frontal y posterior, duración de encendido y apagado de la pantalla;

Capacidad de la batería y estado de carga;

Nivel de fiebre para aliviar el calor;

Modelo y versión del sistema;

....

3. Obtención de indicadores

temperatura

  • temperatura de la batería

El sistema BatteryManger ya proporciona una serie de interfaces integradas y transmisiones fijas para obtener información sobre la batería.

Transmisión BatteryManager.EXTRA_TEMPERATURE, el valor de temperatura obtenido es 10 veces el valor en grados Celsius.

//获取电池温度BatteryManager.EXTRA_TEMPERATURE,华氏温度需要除以10
fun getBatteryTempImmediately(context: Context): Float {
    return try {
        val batIntent = getBatteryStickyIntent(context) ?: return 0f
        batIntent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, 0) / 10F
    } catch (e: Exception) {
        0f
    }
}

private fun getBatteryStickyIntent(context: Context): Intent? {
    return try {
        context.registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
    } catch (e: Exception) {
        null
    }
}

Además de soportar la transmisión del sistema de la temperatura de la batería, BatteryManager también incluye la lectura de información adicional como la energía de la batería y el estado de carga, todo lo cual está definido en su código fuente.

以下罗列几个值得关注的:
//BATTERY_PROPERTY_CHARGE_COUNTER 剩余电池容量,单位为微安时
//BATTERY_PROPERTY_CURRENT_NOW 瞬时电池电流,单位为微安
//BATTERY_PROPERTY_CURRENT_AVERAGE 平均电池电流,单位为微安
//BATTERY_PROPERTY_CAPACITY 剩余电池容量,显示为整数百分比
//BATTERY_PROPERTY_ENERGY_COUNTER 剩余能量,单位为纳瓦时
// EXTRA_BATTERY_LOW  是否认为电量低
// EXTRA_HEALTH  电量健康常量的常数
// EXTRA_LEVEL  电量值
// EXTRA_VOLTAGE 电压
// ACTION_CHARGING   进入充电状态
// ACTION_DISCHARGING  进入放电状态
  • temperatura del sensor

Android es un sistema operativo de código abierto modificado en base a Linux. De manera similar, en el directorio sys/class/thermal/ del sistema de telefonía móvil, hay Thermal_zoneX que representa la zona de temperatura de cada sensor y Cooling_deviceX que representa dispositivos de refrigeración como ventiladores o radiadores. .

Tomando como ejemplo el OnePlus 9, hay un total de 105 sensores de temperatura o particiones de temperatura y 48 dispositivos de refrigeración.

El tipo de parámetro específico se registra debajo de cada partición de temperatura. Nos centramos en el archivo de tipo y el archivo temporal, que registran el nombre del dispositivo sensor y la temperatura actual del sensor, respectivamente. Tomando Thermal_zone29 como ejemplo, el valor de temperatura que representa la quinta unidad de procesamiento del primer núcleo de la CPU es 33,2 grados Celsius. Para un solo dispositivo, el nombre correspondiente a la partición es fijo, por lo que podemos leer el archivo Thermal_zone para registrar el sensor actual cuyo nombre de archivo de primer tipo contiene la CPU como temperatura de la CPU.

  • Temperatura de la caja

Android 10 Google lanzó oficialmente un marco de mitigación térmica, que monitorea los sensores de hardware subyacentes (principalmente sensores USB y sensores Skin) a través del marco HAL2.0 para proporcionar monitoreo de cambios de nivel de señal térmica de temperatura de USB y carcasa. El código fuente de PowerManager del sistema proporciona el nivel de calor correspondiente cambios Hay 7 niveles de adquisición de devolución de llamada y niveles de fiebre, que se proporcionan a los desarrolladores para que los adquieran de forma activa o pasiva.

final PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
powerManager.addThermalStatusListener(new PowerManager.OnThermalStatusChangedListener() {
    @Override
    public void onThermalStatusChanged(int status) {
       //返回对应的热状态
    }
});

Pero en términos de niveles de calor, la temperatura de la carcasa es sin duda la que más refleja el calor del teléfono. Se puede ver que la API del sistema Android en realidad proporciona la interfaz AIDL, y puede registrar directamente el monitoreo del evento de cambio térmico y obtener el objeto Temperatura. Pero desde que se identifica Hide API. No se puede obtener la capa de aplicación normal, teniendo en cuenta la compatibilidad de la versión de Android, se lee a través del proxy de reflexión ThermalManagerService.

Pero contrariamente a lo esperado, los fabricantes nacionales no se han adaptado completamente al marco oficial de mitigación térmica y la devolución de llamada del estado térmico a menudo no es lo suficientemente precisa, sino que necesitan acceder por separado al SDK de mitigación térmica de cada fabricante para obtener directamente la temperatura de la carcasa. La API se basa en los documentos de acceso interno del fabricante de la aplicación.

uso de CPU

El uso de la CPU se recopila y calcula leyendo y analizando el archivo de estadísticas de Proc.

En el sistema proc/[pid]/stat y /proc/[pid]/task/[tid]/stat, la información de la CPU correspondiente al ID del proceso y el ID del subproceso bajo el ID del proceso se registran respectivamente. La descripción del campo específico no se describirá aquí. Para obtener más detalles, consulte: https ://man7.org/linux/man-pages/man5/procfs.5.html .

Nos centramos en los 14,15 bits de información, que representan respectivamente el tiempo de ejecución en modo usuario y el tiempo de ejecución en modo kernel del proceso/hilo.

Al analizar el archivo Stat del proceso actual y los archivos Stat de todos los subprocesos en el directorio de tareas, la diferencia/intervalo de muestreo entre la suma de utime+stime dentro de los dos períodos de muestreo (actualmente establecidos en 1 s) se puede considerar como una entrada de subproceso. .Uso de CPU. Uso inmediato de CPU del subproceso = ((utime+stime)-(lastutime+laststime)) / período

Uso de GPU

Para equipos con chips de Qualcomm, podemos consultar el contenido del archivo en /sys/class/kgsl/kgsl-3d0/gpubusy y las instrucciones en el sitio web oficial de Qualcomm.

Uso de GPU = (imagen a continuación) valor 1 / valor 2 * 100, que se ha verificado que es básicamente consistente con el valor obtenido mediante la recopilación de información de SnapDragonProfiler.

Para los dispositivos con chip MediaTek, podemos leer directamente  el valor de uso en /d/ged/hal/gpu_utilization .

De manera similar, al especificar el intervalo de muestreo del período (1 vez por segundo), se puede obtener el uso actual de GPU por segundo.

Uso del servicio del sistema

Los servicios del sistema Android incluyen Warelock, Alarma, Sensor, Wifi, Red, Ubicación, Bluetooth, Cámara, etc.

Hay poca diferencia con los métodos de monitoreo convencionales en el mercado: todos utilizan el sistema Hook ServiceManager para monitorear la comunicación de Binder del servicio del sistema, hacer coincidir el nombre del método de llamada correspondiente y realizar el procesamiento de registros de devolución de llamada correspondiente al monitoreo de la capa intermedia.

Los estudiantes que están familiarizados con el desarrollo de Android saben que el proceso Zygote de Android es el primer proceso cuando se inicia el sistema Android. En el proceso Zygote Fork, se creará el proceso relacionado con los servicios del sistema SystemServer. En su método principal RUN, una gran cantidad de servicios del sistema se registrarán, iniciarán y administrarán a través de ServiceManager.

Por lo tanto, podemos usar LocationManager como ejemplo para monitorear reflejando el ServiceManager proxy, interceptar los métodos correspondientes en el LocationManager correspondiente y registrar los datos que esperamos obtener.

// 获取 ServiceManager 的 Class 对象
Class<?> serviceManagerClass = Class.forName("android.os.ServiceManager");
// 获取 getService 方法
Method getServiceMethod = serviceManagerClass.getDeclaredMethod("getService", String.class);
// 通过反射调用 getService 方法获取原始的 IBinder 对象
IBinder originalBinder = (IBinder) getServiceMethod.invoke(null, "location");
// 创建一个代理对象 Proxy
Class<?> iLocationManagerStubClass = Class.forName("android.location.ILocationManager$Stub");
Method asInterfaceMethod = iLocationManagerStubClass.getDeclaredMethod("asInterface", IBinder.class);
final Object originalLocationManager = asInterfaceMethod.invoke(null, originalBinder);
Object proxyLocationManager = Proxy.newProxyInstance(context.getClassLoader(),
        new Class[]{Class.forName("android.location.ILocationManager")},
        new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                // 在这里进行方法的拦截和处理
                Log.d("LocationManagerProxy", "Intercepted method: " + method.getName());
                // 执行原始的方法
                return method.invoke(originalLocationManager, args);
            }
        });
// 替换原始的 IBinder 对象
getServiceMethod.invoke(null, "location", proxyLocationManager);

De la misma forma obtenemos registros del número de aplicaciones e intervalos de cálculo para cada servicio del sistema dentro de un período de muestreo fijo.

El archivo de código fuente Power_profile define la cantidad actual en cada estado de servicio del sistema.

Después de que necesitemos registrar el tiempo de trabajo de cada componente en diferentes estados, podemos obtener la clasificación de contribución de calefacción de los componentes mediante el siguiente método de cálculo, a saber:

Consumo de energía del componente (aporte de calor) ~~ Corriente* Tiempo de funcionamiento* Voltaje (generalmente valor fijo, se puede ignorar)

Pila de hilos

Dado que el problema de calentamiento es un problema integral, a diferencia del problema de Crash, podemos saber qué hilo lo desencadenó en el lugar del suceso. Si se vuelcan y registran las pilas de todos los subprocesos, la cantidad de subprocesos que se ejecutan actualmente es más de 200 y, sin duda, no es razonable almacenarlos todos. La pregunta es ¿cómo encontrar con mayor precisión la pila de subprocesos del código activo?

Como se mencionó anteriormente, al calcular el uso de la CPU, leemos los archivos de estadísticas de todos los subprocesos del proceso. Podemos obtener el uso de la CPU de los subprocesos, realizar una clasificación inversa del uso y filtrar los que exceden el umbral. (actualmente definido como 50%) o Se almacenan los subprocesos que ocupan el Top N. Dado que existe una penalización de rendimiento en el momento de la recopilación frecuente de la pila, se sacrifica parte de la precisión y exactitud del muestreo de la pila. Después de que indicadores como la temperatura y el uso de la CPU superen la definición del umbral, se recopilará la información de la pila en el tiempo de liberación especificado.

También necesitamos aclarar un concepto: el nombre del archivo de estadísticas del subproceso es el nombre de identificación del subproceso y Thread.id se refiere a la ID del subproceso.

Los dos no son equivalentes, pero el método Nativo nos proporciona una forma correspondiente de establecer la relación de mapeo entre los dos.

En el método Art Thread.cc, el objeto Thread en Java se convierte en un objeto Thread en C ++ y se llama a ShortDump para imprimir la información relevante del hilo. Podemos obtener el Tid del hilo haciendo coincidir la información principal de Tid = a través de la cuerda. .

La lógica del código central es la siguiente:

//获取队列中最近一次cpu采样的数据
 val threadCpuUsageData = cpuProfileStoreQueue.last().threadUsageDataList
       val hotStacks = mutableListOf<HotStack>()
        if (threadCpuUsageData != null) {
            val dataCount = if (threadCpuUsageData.size <= TOP_THREAD_COUNT) {
                threadCpuUsageData.size
            } else {
                TOP_THREAD_COUNT
            }
            val traces: MutableMap<Thread, Array<StackTraceElement>> = Thread.getAllStackTraces()
            //定义tid 和 thread的映射关系map
            val tidMap: MutableMap<String, Thread> = mutableMapOf()
            traces.keys.forEach { thread ->
                //调用native方法获取到tid信息
                val tidInfo = hotMonitorListener?.findTidInfoByThread(thread)
                tidInfo?.let {
                    findTidByTidInfo(tidInfo).let { tid ->
                        if (tid.isNotEmpty()) {
                            tidMap[tid] = thread
                        }
                    }
                }
            }
            //采集topN的发热堆栈
            for (index in 1..dataCount) {
                val singleThreadData = threadCpuUsageData[index - 1]
                val isMainThread = singleThreadData.pid == singleThreadData.tid
                val thread = tidMap[singleThreadData.tid.toString()]
                thread?.let { findThread ->
                    traces[findThread]?.let { findStackTrace ->
                        //获取当前的线程堆栈
                        val sb = StringBuilder()
                        for (element in findStackTrace) {
                            sb.append(element.toString()).append("\n")
                        }
                        sb.append("\n")
                        if (findStackTrace.isNotEmpty()) {
                            //是否为主线程
                            //组装hotStack
                            val hotStack = HotStack(
                                //进程id
                                singleThreadData.pid,
                                singleThreadData.tid,
                                singleThreadData.name,
                                singleThreadData.cpuUseRate,
                                sb.toString(),
                                thread.state
                                isMainThread
                            )
//                        Log.d("HotMonitor", sb.toString())
                            hotStacks.add(hotStack)
                        }
                    }
                }

            }
        }

4. Plan de seguimiento

Bajo la premisa de comprender cómo se obtienen los datos del indicador central, de hecho, la idea central de la solución de monitoreo no es más que configuraciones de muestreo limitadas, como umbrales de muestreo, ciclos de muestreo e interruptores de datos de cada módulo emitidos por el control remoto. El centro de configuración de APM y el subproceso Handler envían mensajes periódicamente. Los datos de cada módulo se recopilan para el ensamblaje y los datos se informan en el momento adecuado. El trabajo de análisis y desmontaje de datos específicos será procesado posteriormente por la plataforma de calefacción.

Arquitectura general del módulo

tiempo de presentación de informes

Proceso de recolección de núcleos

Distinción online y offline

Dado que la recopilación de CPU y la recopilación de pila de todos los subprocesos en realidad comprometerán el rendimiento, el tiempo total de lectura para más de 200 subprocesos es de aproximadamente 200 ms y el uso de CPU del subproceso de muestreo es del 10%. problemas, el muestreo de alta frecuencia no se puede habilitar completamente.

Por lo tanto, en términos del plan general: el escenario fuera de línea se centra en descubrir, solucionar y gestionar todos los problemas, informar todos los registros y tomar el uso de CPU y GPU como primer indicador de medición;

El escenario en línea se centra en observar la tendencia general del mercado de calefacción, analizar escenarios de problemas potenciales e informar registros centrales, con la temperatura de la batería como primer indicador de medición.

Plataforma calefactora

Con el apoyo de los compañeros de clase en el lado de la plataforma, los datos del campo de calefacción se consumen a través del lado de la plataforma y la pila de calefacción central se agrega a través del servicio anti-ofuscación de la pila de Android para completar campos básicos como el estado de carga, el uso de la CPU del hilo principal, tipo de problema y temperatura de la batería. , el lado de la plataforma tiene la capacidad de descubrir, analizar y resolver el monitoreo y avance basado en procesos.

La plataforma de información de fiebre y de información de pila específica se muestra a continuación:

Dado que la temperatura de la batería y el uso de la CPU son los indicadores más intuitivos para los escenarios de calefacción en tiempo de funcionamiento, y nos centramos en la gestión de los escenarios de calefacción en la primera fase, no realizaremos un análisis continuo en profundidad de los escenarios de consumo de energía, como los ganchos de componentes, por lo que el lado actual de la adquisición se basa en que la temperatura de la batería y el uso de la CPU son el primer y segundo indicador para establecer los cuatro cuadrantes principales de los problemas de calentamiento, dando prioridad a los escenarios de alta temperatura y problemas de CPU.

Durante el proceso de análisis de datos, nos encontramos con situaciones en las que la eficiencia de la resolución de problemas de datos no era lo suficientemente alta y la precisión de las preguntas no era lo suficientemente precisa.

  • ¿Cómo determinar si la escena de alta temperatura ocurre dentro de la aplicación y aumenta significativamente durante el uso? Al filtrar las escenas en las que la temperatura es alta desde el principio y la temperatura es alta al volver al fondo, nos centramos en las escenas en las que la temperatura dentro de la aplicación aumenta.
  • Después del muestreo en línea, todavía se reportan más de 60.000 datos en un solo día. ¿Cómo filtramos más datos básicos? El enfoque actual es definir el concepto de rango de temperatura, dando prioridad a los casos con rangos de temperatura mayores dentro de la aplicación.
  • El subproceso tiene una pila bloqueada mediante la llamada a Wait y otros métodos, lo que consume la asignación de tiempo en el estado del kernel, pero en realidad no consume datos falsos positivos de toda la CPU. El estado de ejecución del subproceso y el estado registrado en el archivo Proc se complementan para facilitar el procesamiento prioritario de la alta temperatura de la CPU y el problema de alto uso del subproceso RUNNABLE.
  • A medida que la temperatura de los teléfonos móviles aumenta gradualmente, ¿cómo lograr una atribución precisa de páginas en el escenario de aumento de temperatura? Si bien se aumenta la frecuencia de muestreo de temperatura, se agregan datos instantáneos como el uso de la CPU y la pila en tiempo real como soporte de datos. Sin embargo, considerando el volumen de datos, el método de agregación y recorte de informes de datos todavía se está explorando gradualmente una forma más razonable, esforzándose por lograr lo mejor entre los dos, encontrar un equilibrio entre ellos.

5. Ingresos

Desde que se lanzó el monitoreo de calentamiento del extremo de Android, con el apoyo de la plataforma, se han descubierto algunos problemas uno tras otro y los estudiantes de desarrollo han trabajado conjuntamente para administrar y optimizar los escenarios correspondientes, tales como:

Las tareas de subprocesos independientes que consumen mucho tiempo están conectadas a la gestión de programación del grupo de subprocesos unificados;

Ejecución de animación, monitoreo y reparación de bucle infinito;

Optimización de estrategias de lectura y escritura de archivos en escenarios de alta IO;

Optimización de la granularidad del bloqueo de tareas de alta concurrencia;

Los escenarios frecuentes de análisis de Json, como las bibliotecas de registros, utilizan métodos de serialización más eficientes;

Intente clasificar los equipos de parámetros de recopilación con una potencia del sistema demasiado alta, como las cámaras del sistema;

La reducción de la velocidad de fotogramas de la escena del juego basada en Webgl y el reciclaje oportuno de recursos optimizan la memoria en tiempo de ejecución;

....

Sin duda, esto ha acumulado una experiencia valiosa para la selección de tecnología de escena y la implementación de tecnología para trabajos de experiencia futuros, que están en línea con los altos estándares y requisitos para la búsqueda definitiva de la experiencia de la aplicación.

6. Perspectivas futuras

Como escenario de experiencia progresiva, el calentamiento de los teléfonos móviles implica múltiples factores, como el hardware del teléfono móvil, los servicios del sistema, el uso del software y el entorno externo. Para la resolución de problemas del lado final, la prioridad actual se centra en el uso irrazonable de la capa de aplicación, incluida la mejora del enlace de la herramienta de resolución de problemas, la atribución comercial de problemas, la batería baja, la reducción de políticas dinámicas en el modo de bajo consumo de energía, los informes de diagnóstico automatizados, etc. Hay muchos puntos que vale la pena profundizar en este enlace, como por ejemplo:

Monitoreo/mejoras de herramientas

  • Herramienta de análisis de capa flotante de aplicaciones (CPU\GPU/frecuencia/temperatura/consumo de energía y otra información)
  • Aprenda de BatteryHistorian, SnapdragonProfiler, Systrace y otras herramientas para mejorar las capacidades del TeslaLab de desarrollo propio.

atribución empresarial

  • La pila de calefacción se asigna automáticamente
  • Trazabilidad de llamadas y refinamiento de la atribución

Estrategia de escenario, degradación

  • Ajuste de CPU, velocidad de cuadros dinámica, degradación de resolución
  • Exploración en modo de bajo consumo de energía en el dispositivo

Informes de diagnóstico automatizados

  • Informe de diagnóstico de salida de análisis automatizado dirigido a un solo usuario

7. Resumen

Esta es solo una introducción aproximada a algunos de los trabajos preliminares que se han realizado para controlar la calefacción, así como ideas para futuros desarrollos relacionados con la calefacción y el consumo de energía. Espero que la aplicación pueda brindar una mejor experiencia y brindar a los usuarios un mayor anhelo. para mejores cosas sentimientos.

*Texto/GavinX

Este artículo es original de Dewu Technology. Para obtener más artículos interesantes, consulte: Sitio web oficial de Dewu Technology

La reimpresión sin el permiso de Dewu Technology está estrictamente prohibida; de lo contrario, se perseguirá la responsabilidad legal de acuerdo con la ley.

Alibaba Cloud sufrió un fallo grave y todos los productos se vieron afectados (restaurados). Tumblr enfrió el sistema operativo ruso Aurora OS 5.0. Se presentó la nueva interfaz de usuario Delphi 12 y C++ Builder 12, RAD Studio 12. Muchas empresas de Internet contratan urgentemente programadores de Hongmeng. Tiempo UNIX está a punto de entrar en la era de los 1.700 millones (ya entró). Meituan recluta tropas y planea desarrollar la aplicación del sistema Hongmeng. Amazon desarrolla un sistema operativo basado en Linux para deshacerse de la dependencia de Android de .NET 8 en Linux. El tamaño independiente es reducido en un 50%. Se lanza FFmpeg 6.1 "Heaviside"
{{o.nombre}}
{{m.nombre}}

Supongo que te gusta

Origin my.oschina.net/u/5783135/blog/10141675
Recomendado
Clasificación