PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Java - CPU-Belastung ermitteln



Emil
22-09-2001, 13:43
Hallo Leute!

"ich hätte gerne ein Problem" :) - ich muß ermitteln, wie hoch die aktuelle JVM die CPU belastet. "Schön", dachte ich - mache ich etwas wie:

Runtime.getRuntime().exec("top -n1 -b -p $PPID");

usw. Denkste! Ohne $PPID funktioniert es wunderbar, nur Parameter mit $ will das Ding nicht erkennen bzw nicht bewerten. Es wurde schon vorgeschlagen, ein Shell-Skript ausführen lassen - passt leider nicht... Weiß jemand Rat, wie man das doch hinkriegen könnte?

Danke im voraus!
Emil

jgbauman
22-09-2001, 15:32
Ueber Runtime.getRuntime().exec() (fork()) ein externes Programm aufzuruefen und dann das Ergebnis zurueckparsen ist sicherlich aufwendig. Je nachdem wie haeufig das geschehen soll kann das ganz schoen viel Zeit beanspruchen.

Wahrscheinlich weil Prozess/Ressourcenacounting sehr systemabhaengig ist, haben die Java-Entwickler AFAIK auf die Entwicklung einer portablen JavaAPI dafuer verzichtet.

Der Linuxkernel stellt aber alle benoetigten Informationen im /proc filesystem zur Verfuegung.

Man kann jetzt eine pure java Loesung basteln die die entsprechenden Dateien parst und die ausloesung errechnet. Da diese Loesung aber sowieso nicht portabel ist (laeuft wegen der Annahmen uber /proc ja nur unter linux) waere das JNI (Java Native Interface - java methoden in C programmiert) eine Alternative.

Grundsaetzliche Idee:
<ul>
<li>Finde den jvm Vaterprozess.
Unter Linux sind Kernel-Threads meist eigene Prozesse und unterliegen der Prozesshierarchie. Moegliche Startegie: laufe vom momentanen Prozess durch die Hierarchie bis das Executable des Vaterprozesses nicht "java" der "jre" ist. Vielleicht gibst ja auch ein passendes System.property das den Namen des executeables (java, jre, java-xyz) kennt. Alternativ koennte auch ein aufrufendes Shellskript die eigene PID als java.property auf der kommandzeile an die JVM uebergeben und diese dann benutzt werden.</li>
<li>Ermitteln der Rechenzeit die der Vaterprozess und seine Kinder erhalten haben
</li>
<li>
Die Auslastung ist jetzt der Quotient der Differenz der gerade ermittelten Rechenzeit und der Rechenzeit zum Zeitpunkt des letzten Aufrufs Funktion und der Differenz der momentanten Zeit und der Zeit des letzten Aufrufs
</li>
</ul>

Die Informationen sind in der Pseudo-Datei /proc/$PID/stat zu finden. Siehe den sprintf()-Befehl in ./fs/proc/array.c get_stat (2.2.x) der proc_pid_stat (2.4.x) als Dokumentation was welche Zahl bedeutet.

Eine JNI-Implementierung waere wahrscheinlich schneller, da dann anstelle von /proc getrusage() benutzt werden kann und das parsen von ASCII entfaellt.


Da die ermitteltne Werte und deren zeitliches Verhalten von den Abfrageintervallen abhaeging sind (grosse Intervalle mitteln kurzzeitige Spitzen, kleine Intervalle koennen zu andauernden grossen Schwankungen fuehren), waere es je nach Anwendung eventuell sinnvoll einen aktives Java-Objekt (Thread) das nur periodisch die Auslastung ermittelt und vom restlichen System konsultiert wird. Vielleicht auch mit einer History der letzten Messwerte um eine Veraenderung feststellen zu koennen.