programacion - Alta utilización de la CPU en aplicaciones java: ¿por qué?
manual de programacion android pdf (5)
Tengo una aplicación Java (basada en web) que a veces muestra una utilización de CPU muy alta (casi el 90%) durante varias horas. El comando TOP
Linux muestra esto. Al reiniciar la aplicación, el problema desaparece.
Así que para investigar :
Tomo Thread Dump para encontrar lo que están haciendo los hilos. Varios ''RUNNABLE''
se encuentran en ''RUNNABLE''
estado ''RUNNABLE''
, algunos en otros pocos estados. Al tomar volcados de subprocesos repetidos, veo algunos subprocesos que siempre están presentes en ''RUNNABLE''
estado ''RUNNABLE''
. Por lo tanto, parecen ser el culpable.
Pero no puedo decir con seguridad qué Hilo está acaparando la CPU o ha entrado en un bucle infinito (lo que provoca un uso elevado de la CPU).
Los registros no necesariamente ayudan, ya que el código ofensivo puede no estar registrando nada.
¿Cómo investigo? ¿Qué parte de la aplicación o qué hilo está causando una alta utilización de la CPU? - ¿Alguna otra idea?
Durante estos tiempos pico de CPU, ¿cómo es la carga del usuario? Usted dice que esta es una aplicación basada en web, por lo que los culpables que vienen a la mente son los problemas de utilización de la memoria. Si almacena un montón de cosas en la sesión, por ejemplo, y el número de sesiones es lo suficientemente alto, el servidor de aplicaciones comenzará a agitarse. Este también es un caso en el que el GC puede empeorar las cosas dependiendo del esquema que esté utilizando. Más información sobre la aplicación y la configuración del servidor sería útil para apuntar hacia más ideas de depuración.
En el volcado de hilos, puede encontrar el Número de línea como se muestra a continuación.
para el hilo principal que se está ejecutando actualmente ...
"main" #1 prio=5 os_prio=0 tid=0x0000000002120800 nid=0x13f4 runnable [0x0000000001d9f000]
java.lang.Thread.State: **RUNNABLE**
at java.io.FileOutputStream.writeBytes(Native Method)
at java.io.FileOutputStream.write(FileOutputStream.java:313)
at com.rana.samples.**HighCPUUtilization.main(HighCPUUtilization.java:17)**
Si un generador de perfiles no es aplicable en su configuración, puede intentar identificar el hilo siguiendo los pasos de esta publicación .
Básicamente, hay tres pasos:
- ejecute
top -H
y obtenga el PID del hilo con la CPU más alta. - Convertir el PID a hexadecimal.
- busque el hilo con el PID HEX coincidente en su volcado de hilo.
Su primer enfoque debe ser encontrar todas las referencias a Thread.sleep y verificar que:
Dormir es lo correcto. Debería usar algún tipo de mecanismo de espera, si es posible, tal vez el uso cuidadoso de un
BlockingQueue
ayudaría.Si dormir es lo correcto, ¿está durmiendo el tiempo correcto? A menudo, esta es una pregunta muy difícil de responder.
El error más común en el diseño de subprocesos múltiples es creer que todo lo que necesita hacer cuando espera que algo suceda es revisarlo y dormir durante un tiempo en un ciclo cerrado. Esto rara vez es una solución efectiva, siempre debe intentar wait
a que ocurra.
El segundo problema más común es hacer un bucle sin dormir . Esto es aún peor y es un poco menos fácil de rastrear.
Usted puede ser víctima de un problema de recolección de basura.
Cuando su aplicación requiere memoria y se está agotando en lo que está configurado para usar, el recolector de basura se ejecutará a menudo, lo que consumirá muchos ciclos de CPU. Si no puede recopilar nada, su memoria permanecerá baja, por lo que se ejecutará una y otra vez. Cuando se vuelve a implementar la aplicación, la memoria se borra y la recolección de basura no se realiza más de lo necesario, por lo que la utilización de la CPU permanece baja hasta que se llena de nuevo.
Debe verificar que no haya una posible pérdida de memoria en su aplicación y que esté bien configurada para la memoria (verifique el parámetro -Xmx
, vea ¿Qué significa la opción Java -Xmx? )
Además, ¿qué estás usando como marco web? JSF depende mucho de las sesiones y consume mucha memoria, ¡considera ser un apátrida a lo sumo!