Voici la réponse à une question posée par un développeur : comment puis-je trouver la charge moyenne du ou des CPU d’un serveur en Java ? Et le tout, sans écrire de JNI ou d’appel natif ?
Java 5 a introduit avec JMX des MBeans simples pour la gestion de mémoire, l’analyse des Threads java, l’accès au système d’exploitation ou encore les paramètres du processus Java en cours.
Dans le package java.lang.managment nous avons les beans suivants :
- java.lang.management.ClassLoadingMXBean
- java.lang.management.CompilationMXBean
- java.lang.management.MemoryManagerMXBean
- o java.lang.management.GarbageCollectorMXBean
- java.lang.management.MemoryMXBean
- java.lang.management.MemoryPoolMXBean
- java.lang.management.OperatingSystemMXBean
- java.lang.management.RuntimeMXBean
- java.lang.management.ThreadMXBean
Pour notre problème de CPU et de charge, le bean OperatingSystemMXBean permettra de lire quelques informations sur le système d’exploitation. Ce bean est disponible à partir de Java 5. Mais il vous faudra Java 6 obligatoirement pour trouver la charge moyenne de la machine. Nous allons utiliser tout simplement la méthode getSystemLoadAverage() qui retourne la charge CPU moyenne des dernières 60 secondes. Le code sera le suivant :
import java.lang.management.ManagementFactory; import java.lang.management.OperatingSystemMXBean; /** * Sample that uses the JMX OperatingSystemMXBean bean to collect various information * about the operating system, the number of CPU, and the load average from Java. * This code works with Java 6 cause getSystemLoadAverage is available only with Java 6. * * @author nicolas.martignole * @version created on 23-May-2008 * @since 1.6 */ public class TestLoadAverage { public static void main(String[] args) { OperatingSystemMXBean bean = ManagementFactory.getOperatingSystemMXBean(); if (bean == null) throw new NullPointerException("Unable to collect operating system metrics, jmx bean is null"); System.out.println("System architecture : " + bean.getArch()); System.out.println("Number of processor(s) : " + bean.getAvailableProcessors()); System.out.println("Operating system name : " + bean.getName()); System.out.println("Operating system version : " + bean.getVersion()); // Returns the system load average for the last minute. // Java 6 only System.out.println("System load average for the last minute : "+bean.getSystemLoadAverage()); } }
Lorsque j’exécute ce code sur mon portable (un vieux T42) avec un processeur mono-coeur, voici l’affichage retourné :
System architecture : x86
Number of processor(s) : 1
Operating system name : Windows XP
Operating system version : 5.1
System load average for the last minute : -1
La mauvaise nouvelle est que sur Windows, la méthode getSystemLoadAverage n’est pas implémentée. Elle retournera -1. Sur une machine double-coeur, le nombre de processeur retourné est bien 2. J’ai fait le test avec un T60 d’IBM équipé d’un Intel Core 2 Duo.
Pour notre problème de CPU, nous travaillons sur Solaris. Voici le résultat d’un test sur une Sun. Il s’agit d’une V440 quadri processeurs avec Solaris 10. On peut constater que cette fois-ci, Java 6 retourne la charge moyenne du CPU des 60 dernières secondes.
[nicmarti@ptxskarma nicmarti]% uname -a
SunOS ptxskarma 5.10 Generic_118833-36 sun4u sparc SUNW,Sun-Fire-V440
[nicmarti@ptxskarma nicmarti]% java -version
java version "1.6.0_01"
Java(TM) SE Runtime Environment (build 1.6.0_01-b06)
Java HotSpot(TM) Server VM (build 1.6.0_01-b06, mixed mode)
[nicmarti@ptxskarma nicmarti]% java TestLoadAverage
System architecture : sparc
Number of processor(s) : 4
Operating system name : SunOS
Operating system version : 5.10
System load average for the last minute : 0.328125
[nicmarti@ptxskarma nicmarti]%
Statistiques sur les Threads
De la même manière vous pouvez aussi écrire rapidement du code en java pour surveiller les Threads Java de votre application. Il est ainsi possible de compter le nombre de threads java démarrées dans la JVM, de voir si une thread est active ou en attente par exemple. Voici un autre exemple de code que vous pouvez très facilement adapter en lisant la javadoc de ThreadMXBean
import java.lang.management.ManagementFactory; import java.lang.management.ThreadMXBean; import java.lang.management.ThreadInfo; /** * This sample collects java Thread details using Java 5 Managment capabilities. * Java 5 or 6 is required. * * @author nicolas.martignole * @version created on 23-May-2008 */ public class TestThreads { public static void main(String[] args) { ThreadMXBean bean = ManagementFactory.getThreadMXBean(); if (!bean.isThreadCpuTimeSupported()) { System.out.println("Sorrt, the Java virtual machine implementation does not support CPU time measurement for any thread."); System.exit(-1); } if (!bean.isCurrentThreadCpuTimeSupported()) { System.out.println("Sorry, JVM does not supports CPU time measurement for the current thread"); System.exit(-1); } if (!bean.isThreadCpuTimeEnabled()) { System.out.println("Sorry, Thread CPU measurement is not enabled"); System.exit(-1); } showThreadIds(bean); } /** * This method shows some threads informations. * * @param bean is the ThreadMXBean. */ private static void showThreadIds(ThreadMXBean bean) { for (long id : bean.getAllThreadIds()) { System.out.println("ID " + id); showThreadInfo(bean, id); } } /** * Show interesting details about a thread. * * @param bean * @param id is the thread id. */ private static void showThreadInfo(ThreadMXBean bean, long id) { ThreadInfo info = bean.getThreadInfo(id); System.out.println("java thread name: " + info.getThreadName()); System.out.println("java thread state: " + info.getThreadState()); System.out.println("Thread CPU Time : "+ bean.getThreadCpuTime(id)); System.out.println("Thread peak time: "+bean.getPeakThreadCount()); } }
Information sur la JVM comme le Classpath
Le bean RuntimeMXBean permet de lire un certain nombre d’informations intéressantes sur le processus Java en cours. Vous pouvez ainsi retrouver le classpath, le bootclasspath ce qui est utile lorsque vous jouez avec Xalan ou Xerces. Vous pouvez aussi lire depuis combien de temps le processus Java a démarré (uptime) ainsi que l’implémentation de la JVM en cours (SUN ? Bea ? IBM ?). Vous avez accès aux proprietés systèmes sous la forme d’une Map et donc, au PATH sous unix par exemple. Vous avez aussi accès aux paramètres de la ligne de commande du processus java, afin de voir par ailleurs ce qui a été passé en argument au processus Java.
Conclusion
Je vous conseille de prendre quelques minutes pour voir la liste des différents MBean d’administration et de surveillance qui sont disponibles en Java. Ceux concernant la gestion de la mémoire par exemple sont aussi très puissants.
Voir la liste complète sur cette page : Package java.lang.managment Java SE 6. En espérant que ce post aidera quelques uns d’entre nous.
0 no like
Bonjour, merci pour ce blog intereesant.
De mon côté, j’utilise la jconsole. Elle posséde tout ce qui faut.
De plus vous pouvez ajouter des donné perso grace à un mecanisme simple.
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
try
{
ObjectName name = new ObjectName(« com.toto:type=monType,attribut=attt1 »);
mbs.registerMBean(this, name);
}
catch (Exception e)
{
LOGGER.error(e, e);
}