サーバーでjstackを使用して、Javaアプリがデッドロックしているかどうかを検出します。Linuxサーバーの1つでは機能していません。O/ Sバージョンは次のとおりです。
$cat /etc/issue.net
Red Hat Enterprise Linux Server release 5.6 (Tikanga)
Kernel \r on an \m
サーバーで実行されているJavaバージョン:
Java version "1.6.0_24"
Java(TM) SE Runtime Environment (build 1.6.0_24-b07)
Java HotSpot(TM) 64-Bit Server VM (build 19.1-b02, mixed mode)
私が試してみると:
jstack 19114
私は得る:
19114: Unable to open socket file: target process not responding or HotSpot VM not loaded
The -F option can be used when the target process is not responding
私が試してみると:
jstack -F 19114
私は得る:
Attaching to process ID 19114, please wait...
Debugger attached successfully.
Deadlock Detection:
No deadlocks found.
Thread 19180: (state = BLOCKED)
Error occurred during stack walking:
Sun.jvm.hotspot.debugger.DebuggerException: Sun.jvm.hotspot.debugger.DebuggerException: get_thread_regs failed for a lwp
at Sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal$LinuxDebuggerLocalWorkerThread.execute(LinuxDebuggerLocal.Java:152)
at Sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal.getThreadIntegerRegisterSet(LinuxDebuggerLocal.Java:466)
at Sun.jvm.hotspot.debugger.linux.LinuxThread.getContext(LinuxThread.Java:65)
at Sun.jvm.hotspot.runtime.linux_AMD64.LinuxAMD64JavaThreadPDAccess.getCurrentFrameGuess(LinuxAMD64JavaThreadPDAccess.Java:92)
at Sun.jvm.hotspot.runtime.JavaThread.getCurrentFrameGuess(JavaThread.Java:256)
at Sun.jvm.hotspot.runtime.JavaThread.getLastJavaVFrameDbg(JavaThread.Java:218)
at Sun.jvm.hotspot.tools.StackTrace.run(StackTrace.Java:76)
at Sun.jvm.hotspot.tools.StackTrace.run(StackTrace.Java:45)
at Sun.jvm.hotspot.tools.JStack.run(JStack.Java:60)
at Sun.jvm.hotspot.tools.Tool.start(Tool.Java:221)
at Sun.jvm.hotspot.tools.JStack.main(JStack.Java:86)
at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:39)
at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:25)
at Java.lang.reflect.Method.invoke(Method.Java:597)
at Sun.tools.jstack.JStack.runJStackTool(JStack.Java:118)
at Sun.tools.jstack.JStack.main(JStack.Java:84)
Caused by: Sun.jvm.hotspot.debugger.DebuggerException: get_thread_regs failed for a lwp
at Sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal.getThreadIntegerRegisterSet0(Native Method)
at Sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal.access$800(LinuxDebuggerLocal.Java:51)
at Sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal$1GetThreadIntegerRegisterSetTask.doit(LinuxDebuggerLocal.Java:460)
at Sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal$LinuxDebuggerLocalWorkerThread.run(LinuxDebuggerLocal.Java:127)
誰がこれを引き起こしているのか知っていますか?
Javaプロセスを開始したのと同じユーザーとしてjstackを実行する必要があります。これにより、上記のスタックトレースエラーが解決されます。この投稿を参照してください: jstackスレッドダンプエラー:get_thread_regsがlwpで失敗しました 詳細については、jstackコマンドを実行するとすぐに、エラーは消えました。
構文は単純です。
Sudo -u USERID jstack PID
例:
Sudo -u Tomcat7 jstack 2498
代わりに、同様の出力を提供するjspを使用できます。
次のjspは、スレッドスタック情報を画面に出力しますが、出力をファイルに変更したり、通常のPOJOクラスで使用したりすることもできます。
<%@ page import="Java.util.*" %><%
Map<Thread,StackTraceElement[]> map = Thread.getAllStackTraces();
Set tt = map.keySet();
Iterator<Thread> ti = tt.iterator();
Thread thrd = null;
final String br = "<" + "br" + ">";//website does not parse it
try{
int cnt = 1;
StackTraceElement[] st = null;
while(ti.hasNext() ){
thrd = ti.next();
out.print(br + "<" + "hr" + ">" + br + cnt + " \"" + thrd.getName());
out.println("\", priority :" + thrd.getPriority() + ", state :" + thrd.getState());
out.print(", id :" + thrd.getId() + ", hex :" + Long.toHexString(thrd.getId()) );
out.print(" alive :" + thrd.isAlive() + ", daemon :" + thrd.isDaemon() );
out.print(" interrupted :" + thrd.isInterrupted() + ", daemon :" + thrd.isDaemon() );
out.print(".\n" + br);
st = thrd.getStackTrace();
for(int sti = 0; sti < st.length; sti++){
out.println(br + " " + st[sti].getClassName() + "." + st[sti].getMethodName());
out.println("(" + st[sti].getFileName());
if(st[sti].getLineNumber() < 1){
out.print("Native method");
}else{
out.print(":" + st[sti].getLineNumber());
}
out.println(")");
}
out.println("");
cnt++;
}
}catch(Exception e){
out.println(br + "err " + e + br);
}
%>
サンプル出力:
121 "スレッド-40"、優先度:6、状態:待機中、ID:134、16進数:86生きている:true、デーモン:false中断:false、デーモン:false。
Java.lang.Object.wait(Object.Javaネイティブメソッド)
Java.lang.Object.wait(Object.Java:485)
org.jpos.iso.ISOMUX $ Receiver.run(ISOMUX.Java:326)
Java.lang.Thread.run(Thread.Java:662)122 "スレッド-48"、優先度:5、状態:TIMED_WAITING、ID:142、16進数:8eアライブ:true、デーモン:false割り込み:false、デーモン:false。
Java.lang.Thread.sleep(Thread.Javaネイティブメソッド)
org.jpos.apps.qsp.QSP.monitorConfigFile(QSP.Java:301)
org.jpos.apps.qsp.QSP.run(QSP.Java:346)
Java.lang.Thread.run(Thread.Java:662)
代わりにkill -3 <pid>
を使用して、VMのスタックトレースを取得してみてください。