it-swarm.com.de

Hohe CPU-Auslastung in Java-Anwendungen - warum?

Ich habe eine Java-Anwendung (webbasiert), die zeitweise eine sehr hohe CPU-Auslastung (fast 90%) für mehrere Stunden aufweist. Der Linux-Befehl TOP zeigt dies. Beim Neustart der Anwendung wird das Problem behoben.

So zu untersuchen:

Ich nehme Thread Dump, um herauszufinden, was Threads machen. Einige Threads befinden sich im 'RUNNABLE'-Status, einige in wenigen anderen Status. Bei wiederholten Thread-Dumps sehe ich einige Threads, die immer im 'RUNNABLE'-Status vorhanden sind. Sie scheinen also der Täter zu sein.

Ich kann aber nicht genau sagen, welcher Thread die CPU belastet oder in eine Endlosschleife geraten ist (was zu einer hohen CPU-Auslastung führt).

Protokolle helfen nicht unbedingt, da der fehlerhafte Code möglicherweise nichts protokolliert.

Wie untersuche ich - Welcher Teil der Anwendung oder welcher Thread verursacht eine hohe CPU-Auslastung? - Irgendwelche anderen Ideen? 

29
Jasper

Wenn ein Profiler in Ihrem Setup nicht anwendbar ist, versuchen Sie möglicherweise, den Thread anhand der Schritte in this post zu identifizieren.

Grundsätzlich gibt es drei Schritte:

  1. führen Sie top -H aus und erhalten Sie die PID des Threads mit der höchsten CPU.
  2. wandle die PID in hex um.
  3. suchen Sie nach dem Thread mit der entsprechenden HEX-PID in Ihrem Thread-Dump.
38
ericson

Sie könnten Opfer eines Müllsammelproblems werden.

Wenn für Ihre Anwendung Speicher erforderlich ist und die für die Verwendung des Garbage Collector zu wenig genutzten Speicherkapazitäten ausreichen, werden viele CPU-Zyklen beansprucht. Wenn nichts gesammelt werden kann, bleibt Ihr Speicher niedrig, sodass er erneut ausgeführt wird und wieder ... Wenn Sie Ihre Anwendung erneut bereitstellen, wird der Speicher gelöscht und die Speicherbereinigung wird nicht mehr als erforderlich ausgeführt, sodass die CPU-Auslastung niedrig bleibt, bis sie wieder voll ist.

Sie sollten prüfen, ob in Ihrer Anwendung kein möglicher Speicherverlust vorliegt und dass sie für den Speicher gut konfiguriert ist (überprüfen Sie den Parameter -Xmx, siehe Wofür steht die Java-Option -Xmx? )

Was verwenden Sie auch als Web-Framework? JSF ist viel auf Sitzungen angewiesen und verbraucht viel Speicher.

12
Alexandre Jacob

Wie ist der Benutzer während dieser Spitzenzeiten der CPU? Sie sagen, es handelt sich um eine webbasierte Anwendung. Die Schuldigen sind daher Probleme bei der Speicherauslastung. Wenn Sie beispielsweise viel in der Sitzung speichern und die Anzahl der Sitzungen hoch genug ist, wird der App-Server durcheinander geraten. Dies ist auch ein Fall, in dem der GC je nach verwendetem Schema die Sache verschlimmern kann. Weitere Informationen zur App und zur Serverkonfiguration sind hilfreich, wenn Sie auf weitere Debugging-Ideen hinweisen möchten.

2
WPrecht

Im Thread-Dump finden Sie die Zeilennummer wie folgt.

für den Haupt-Thread, der gerade läuft ...

"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)**
1
ranafeb14

Zunächst sollten Sie alle Verweise auf Thread.sleep suchen und Folgendes prüfen:

  1. Schlafen ist das Richtige - Sie sollten, wenn möglich, einen Wartemechanismus verwenden - vielleicht hilft ein sorgfältiger Einsatz einer BlockingQueue.

  2. Wenn Sie ist das Richtige tun, schlafen Sie für die richtige Zeit - dies ist oft eine sehr schwierige Frage.

Der häufigste Fehler beim Multithreaded-Design besteht darin zu glauben, dass alles, was Sie tun müssen, um zu warten, dass etwas passiert, darin zu suchen und in einer engen Schleife eine Weile zu schlafen. Dies ist selten eine effektive Lösung - Sie sollten immer versuchen, für das Vorkommen wait zu versuchen.

Das zweithäufigste Problem ist das Schleifen von ohne zu schlafen. Dies ist noch schlimmer und lässt sich etwas weniger leicht aufspüren.

1
OldCurmudgeon

Sie haben der Frage nicht "Linux" zugewiesen, sondern "Linux top" erwähnt. Und so könnte dies hilfreich sein:

Verwenden Sie das kleine Linux-Tool threadcpu, um die CPU mit den meisten Threads zu identifizieren. Es ruft jstack auf, um den Threadnamen abzurufen. Und mit "sort -n" in der Pipe erhalten Sie die Liste der Threads, die nach CPU-Nutzung geordnet sind.

Weitere Informationen finden Sie hier: http://www.tuxad.com/blog/archives/2018/10/01/threadcpu_-_show_cpu_usage_of_threads/index.html

Wenn Sie noch weitere Details benötigen, erstellen Sie einen Thread-Dump oder führen Sie strace im Thread aus.

0
reichhart