AIX® -Blockierungen mit hoher Auslastung
Wenn kein Deadlock zwischen den Threads vorliegt, sollten Sie nach anderen Ursachen suchen, weshalb die Threads nicht funktionieren.
- Threads befinden sich im Wartestatus und warten auf Benachrichtigungen über zu erledigende Aufgaben.
- Threads befinden sich in einem expliziten Standbyzyklus.
- Threads befinden sich in E/A-Aufrufen und warten auf auszuführende Arbeiten.
Der dritte Grund, bei dem Threads auf eine Eingabe/Ausgabe warten (z. B. auf Sockets) muss näher untersucht werden. Ist der Prozess am anderen Ende der Ein-/Ausgabe fehlgeschlagen? Liegen Netzprobleme vor?
Informationen dazu, wie das Java-Speicherauszug-Tool zur Diagnose von Schleifen verwendet wird, finden Sie unter THREADS. Wenn Sie das Problem nicht anhand des Javadumps diagnostizieren können und der Prozess weiterhin Prozessorzyklen zu verwenden scheint, befindet er sich entweder in einer Endlosschleife oder wird durch eine sehr schlechte Leistung verursacht. Mit dem Befehl ps -mp [process id] -o THREAD können Sie einzelne Threads in einem bestimmten Prozess überwachen und feststellen, welche Threads die CPU-Zeit belegen. Wenn sich der Prozess in einer Endlosschleife befindet, wird die Zeit wahrscheinlich von wenigen Threads belegt. Beispiel:
$ ps -mp 43824 -o THREAD
USER PID PPID TID ST CP PRI SC WCHAN F TT BND COMMAND
wsuser 43824 51762 - A 66 60 77 * 200001 pts/4 - java ...
- - - 4021 S 0 60 1 22c4d670 c00400 - - -
- - - 11343 S 0 60 1 e6002cbc 8400400 - - -
- - - 14289 S 0 60 1 22c4d670 c00400 - - -
- - - 14379 S 0 60 1 22c4d670 c00400 - - -
...
- - - 43187 S 0 60 1 701e6114 400400 - - -
- - - 43939 R 33 76 1 20039c88 c00000 - - -
- - - 50275 S 0 60 1 22c4d670 c00400 - - -
- - - 52477 S 0 60 1 e600ccbc 8400400 - - -
...
- - - 98911 S 0 60 1 7023d46c 400400 - - -
- - - 99345 R 33 76 0 - 400000 - - -
- - - 99877 S 0 60 1 22c4d670 c00400 - - -
- - - 100661 S 0 60 1 22c4d670 c00400 - - -
- - - 102599 S 0 60 1 22c4d670 c00400 - - -
...
Die Threads mit dem Wert 'R' unter 'ST' befinden sich in einem 'ausführbaren' Status und können daher Prozessorzeiten akkumulieren. Womit sind diese Threads beschäftigt? Die Ausgabe von ps zeigt die TID (Kernel-Thread-ID) für jeden Thread. Diese kann mit dbxder Java-Thread-ID zugeordnet werden. Die Ausgabe des dbx-Befehls thread hat folgendes Format:
thread state-k wchan state-u k-tid mode held scope function
$t1 wait 0xe60196bc blocked 104099 k no sys _pthread_ksleep
>$t2 run blocked 68851 k no sys _pthread_ksleep
$t3 wait 0x2015a458 running 29871 k no sys pthread_mutex_lock
...
$t50 wait running 86077 k no sys getLinkRegister
$t51 run running 43939 u no sys reverseHandle
$t52 wait running 56273 k no sys getLinkRegister
$t53 wait running 37797 k no sys getLinkRegister
$t60 wait running 4021 k no sys getLinkRegister
$t61 wait running 18791 k no sys getLinkRegister
$t62 wait running 99345 k no sys getLinkRegister
$t63 wait running 20995 k no sys getLinkRegister
Wenn Sie den TID-Wert von ps mit dem Wert k-tid des dbx-Befehls thread abgleichen, sehen Sie, dass 'reverseHandle' und 'getLinkRegister' hier die derzeit aktiven Methoden sind.
Jetzt können Sie mithilfe des Befehls dbx den C-Thread-Stack für diese beiden Threads generieren. Verwenden Sie den dbx-Befehl thread für die entsprechenden dbx-Threadnummern ($tx). Um den vollständigen Stack-Trace einschließlich Java-Frames abzurufen, ordnen Sie die dbx-Threadnummer dem Wert pthread_t für Threads zu, der in der Java-Speicherauszugsdatei aufgelistet ist und über die Speicherauszugsanzeige aus der Struktur ExecEnv für jeden Thread abgerufen werden kann. Verwenden Sie hierfür den dbx-Befehl thread
info [dbx thread number], der folgende Ausgabe generiert:
thread state-k wchan state-u k-tid mode held scope function
$t51 run running 43939 u no sys reverseHandle
general:
pthread addr = 0x220c2dc0 size = 0x18c
vp addr = 0x22109f94 size = 0x284
thread errno = 61
start pc = 0xf04b4e64
joinable = yes
pthread_t = 3233
scheduler:
kernel =
user = 1 (other)
event :
event = 0x0
cancel = enabled, deferred, not pending
stack storage:
base = 0x220c8018 size = 0x40000
limit = 0x22108018
sp = 0x22106930
Der TID-Wert von ps (k-tid in dbx) entspricht der dbx-Threadnummer 51, die eine pthread_t von 3233 hat. Wenn Sie in der Java-Speicherauszugsdatei nach dem Wert für pthread_t suchen, haben Sie einen vollständigen Stack-Trace:
"Worker#31" (TID:0x36288b10, sys_thread_t:0x220c2db8) Native Thread State:
ThreadID: 00003233 Reuse: 1 USER SUSPENDED Native Stack Data : base: 22107f80
pointer 22106390 used(7152) free(250896)
----- Monitors held -----
java.io.OutputStreamWriter@3636a930
com.ibm.servlet.engine.webapp.BufferedWriter@3636be78
com.ibm.servlet.engine.webapp.WebAppRequestDispatcher@3636c270
com.ibm.servlet.engine.srt.SRTOutputStream@36941820
com.ibm.servlet.engine.oselistener.nativeEntry.NativeServerConnection@36d84490 JNI pinning lock
----- Native stack -----
_spin_lock_global_common pthread_mutex_lock - blocked on Heap Lock
sysMonitorEnterQuicker sysMonitorEnter unpin_object unpinObj
jni_ReleaseScalarArrayElements jni_ReleaseByteArrayElements
Java_com_ibm_servlet_engine_oselistener_nativeEntry_NativeServerConnection_nativeWrite
------ Java stack ------ () prio=5
com.ibm.servlet.engine.oselistener.nativeEntry.NativeServerConnection.write(Compiled Code)
com.ibm.servlet.engine.srp.SRPConnection.write(Compiled Code)
com.ibm.servlet.engine.srt.SRTOutputStream.write(Compiled Code)
java.io.OutputStreamWriter.flushBuffer(Compiled Code)
java.io.OutputStreamWriter.flush(Compiled Code)
java.io.PrintWriter.flush(Compiled Code)
com.ibm.servlet.engine.webapp.BufferedWriter.flushChars(Compiled Code)
com.ibm.servlet.engine.webapp.BufferedWriter.write(Compiled Code)
java.io.Writer.write(Compiled Code)
java.io.PrintWriter.write(Compiled Code)
java.io.PrintWriter.write(Compiled Code)
java.io.PrintWriter.print(Compiled Code)
java.io.PrintWriter.println(Compiled Code)
pagecompile._identifycustomer_xjsp.service(Compiled Code)
javax.servlet.http.HttpServlet.service(Compiled Code)
com.ibm.servlet.jsp.http.pagecompile.JSPState.service(Compiled Code)
com.ibm.servlet.jsp.http.pagecompile.PageCompileServlet.doService(Compiled Code)
com.ibm.servlet.jsp.http.pagecompile.PageCompileServlet.doGet(Compiled Code)
javax.servlet.http.HttpServlet.service(Compiled Code)
javax.servlet.http.HttpServlet.service(Compiled Code)
Mithilfe des vollständigen Stack-Trace sollten jegliche Endlosschleifen identifiziert werden können, die möglicherweise auftreten. Das vorherige Beispiel zeigt die Verwendung von spin_lock_global_common, einem aktiven Warten auf eine Sperre, also der CPU-Zeit.