通过jstack分析解决进程死锁问题实例代码
刚才用jstack解决了一个进程死锁的问题——其实早就解决了,也知道原因,只是一直没找到死锁的位置,不太甘心而已。
流程大致如下:
(0)环境要求,JDK1.6及以上
(1)先找到进程的PID,Windows下,打开进程管理器,按照名字排序,可以找到叫做javaw.exe的进程(java虚拟机进程一律叫做javaw.exe),要找出哪个是你的进程,记住当前进程列表,然后重启你的进程,PID刷新过的那个即是你的进程。
(2)在CMD下运行:jstackpid,jstack会在console上打出一系列信息
(3)分析上述信息
实例:
我这个问题的的jstack信息如下:
C:\DocumentsandSettings\user>jstack6652 2012-06-0721:32:02 FullthreaddumpJavaHotSpot(TM)ClientVM(16.3-b01mixedmode,sharing): "Thread-1"daemonprio=6tid=0x03010c00nid=0xcdcwaitingformonitorentry[0x0 339f000] java.lang.Thread.State:BLOCKED(onobjectmonitor) atorg.apache.commons.net.telnet.TelnetInputStream.__read(TelnetInputStr eam.java:122) -waitingtolock<0x22942280>(aorg.apache.commons.net.ftp.FTPClient) atorg.apache.commons.net.telnet.TelnetInputStream.run(TelnetInputStream .java:535) atjava.lang.Thread.run(Thread.java:619) "FrameworkEventDispatcher"daemonprio=6tid=0x03010400nid=0x998inObject.wa it()[0x0334f000] java.lang.Thread.State:WAITING(onobjectmonitor) atjava.lang.Object.wait(NativeMethod) -waitingon<0x228fa800>(aorg.eclipse.osgi.framework.eventmgr.EventMa nager$EventThread) atjava.lang.Object.wait(Object.java:485) atorg.eclipse.osgi.framework.eventmgr.EventManager$EventThread.getNextE vent(EventManager.java:400) -locked<0x228fa800>(aorg.eclipse.osgi.framework.eventmgr.EventManage r$EventThread) atorg.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(Even tManager.java:336) "StartLevelEventDispatcher"daemonprio=6tid=0x02fcf400nid=0x2638inObject .wait()[0x032de000] java.lang.Thread.State:WAITING(onobjectmonitor) atjava.lang.Object.wait(NativeMethod) -waitingon<0x2295db48>(a[I) atjava.lang.Object.wait(Object.java:485) atorg.apache.commons.net.telnet.TelnetInputStream.read(TelnetInputStrea m.java:339) -locked<0x2295db48>(a[I) atorg.apache.commons.net.telnet.TelnetInputStream.read(TelnetInputStrea m.java:466) atjava.io.BufferedInputStream.read1(BufferedInputStream.java:256) atjava.io.BufferedInputStream.read(BufferedInputStream.java:317) -locked<0x2295fe18>(ajava.io.BufferedInputStream) atsun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264) atsun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306) atsun.nio.cs.StreamDecoder.read(StreamDecoder.java:158) -locked<0x22961f88>(ajava.io.InputStreamReader) atjava.io.InputStreamReader.read(InputStreamReader.java:167) atjava.io.BufferedReader.fill(BufferedReader.java:136) atjava.io.BufferedReader.readLine(BufferedReader.java:299) -locked<0x22961f88>(ajava.io.InputStreamReader) atjava.io.BufferedReader.readLine(BufferedReader.java:362) atorg.apache.commons.net.ftp.FTP.__getReply(FTP.java:264) atorg.apache.commons.net.ftp.FTP._connectAction_(FTP.java:335) atorg.apache.commons.net.ftp.FTPClient._connectAction_(FTPClient.java:5 50) atorg.apache.commons.net.SocketClient.connect(SocketClient.java:163) atcom.mycompany.dc.ftp.client.FTPClientImpl.connect(FTPClientImpl.java:7 5) -locked<0x22942280>(aorg.apache.commons.net.ftp.FTPClient) atcom.mycompany.dc.ftp.client.FTPClientFactoryImpl.getClient(FTPClientFa ctoryImpl.java:35) -locked<0x228f9310>(ajava.lang.Object) atftpclienttest.Activator.start(Activator.java:43) atorg.eclipse.osgi.framework.internal.core.BundleContextImpl$1.run(Bund leContextImpl.java:711) atjava.security.AccessController.doPrivileged(NativeMethod) atorg.eclipse.osgi.framework.internal.core.BundleContextImpl.startActiv ator(BundleContextImpl.java:702) atorg.eclipse.osgi.framework.internal.core.BundleContextImpl.start(Bund leContextImpl.java:683) atorg.eclipse.osgi.framework.internal.core.BundleHost.startWorker(Bundl eHost.java:381) atorg.eclipse.osgi.framework.internal.core.AbstractBundle.resume(Abstra ctBundle.java:389) atorg.eclipse.osgi.framework.internal.core.Framework.resumeBundle(Frame work.java:1131) atorg.eclipse.osgi.framework.internal.core.StartLevelManager.resumeBund les(StartLevelManager.java:559) atorg.eclipse.osgi.framework.internal.core.StartLevelManager.resumeBund les(StartLevelManager.java:544) atorg.eclipse.osgi.framework.internal.core.StartLevelManager.incFWSL(St artLevelManager.java:457) atorg.eclipse.osgi.framework.internal.core.StartLevelManager.doSetStart Level(StartLevelManager.java:243) -locked<0x27e68d70>(ajava.lang.Object) atorg.eclipse.osgi.framework.internal.core.StartLevelManager.dispatchEv ent(StartLevelManager.java:438) atorg.eclipse.osgi.framework.internal.core.StartLevelManager.dispatchEv ent(StartLevelManager.java:1) atorg.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventM anager.java:230) atorg.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(Even tManager.java:340) "FrameworkActiveThread"prio=6tid=0x02ff1800nid=0x1fbcinObject.wait()[0x0 328f000] java.lang.Thread.State:TIMED_WAITING(onobjectmonitor) atjava.lang.Object.wait(NativeMethod) -waitingon<0x27e65770>(aorg.eclipse.osgi.framework.internal.core.Fr amework) atorg.eclipse.osgi.framework.internal.core.Framework.run(Framework.java :1817) -locked<0x27e65770>(aorg.eclipse.osgi.framework.internal.core.Framew ork) atjava.lang.Thread.run(Thread.java:619) "OSGiConsole"prio=6tid=0x03005400nid=0x225cwaitingoncondition[0x0323f000 ] java.lang.Thread.State:TIMED_WAITING(sleeping) atjava.lang.Thread.sleep(NativeMethod) atorg.eclipse.osgi.framework.internal.core.FrameworkConsole.runConsole( FrameworkConsole.java:125) atorg.eclipse.osgi.framework.internal.core.FrameworkConsole.run(Framewo rkConsole.java:104) atjava.lang.Thread.run(Thread.java:619) "LowMemoryDetector"daemonprio=6tid=0x02c09800nid=0x1d68runnable[0x000000 00] java.lang.Thread.State:RUNNABLE "CompilerThread0"daemonprio=10tid=0x02c03000nid=0x24c4waitingoncondition [0x00000000] java.lang.Thread.State:RUNNABLE "AttachListener"daemonprio=10tid=0x02c01800nid=0x1138waitingoncondition [0x00000000] java.lang.Thread.State:RUNNABLE "SignalDispatcher"daemonprio=10tid=0x02c20c00nid=0x18acrunnable[0x0000000 0] java.lang.Thread.State:RUNNABLE "Finalizer"daemonprio=8tid=0x02bc0400nid=0x11acinObject.wait()[0x02d8f000 ] java.lang.Thread.State:WAITING(onobjectmonitor) atjava.lang.Object.wait(NativeMethod) -waitingon<0x27d5e5c8>(ajava.lang.ref.ReferenceQueue$Lock) atjava.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118) -locked<0x27d5e5c8>(ajava.lang.ref.ReferenceQueue$Lock) atjava.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134) atjava.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159) "ReferenceHandler"daemonprio=10tid=0x02bbb800nid=0x9ccinObject.wait()[0x 02d3f000] java.lang.Thread.State:WAITING(onobjectmonitor) atjava.lang.Object.wait(NativeMethod) -waitingon<0x27d5e650>(ajava.lang.ref.Reference$Lock) atjava.lang.Object.wait(Object.java:485) atjava.lang.ref.Reference$ReferenceHandler.run(Reference.java:116) -locked<0x27d5e650>(ajava.lang.ref.Reference$Lock) "main"prio=6tid=0x008a6c00nid=0x22ecinObject.wait()[0x0098f000] java.lang.Thread.State:TIMED_WAITING(onobjectmonitor) atjava.lang.Object.wait(NativeMethod) -waitingon<0x22c303c8>(aorg.eclipse.core.runtime.internal.adaptor.S emaphore) atorg.eclipse.core.runtime.internal.adaptor.Semaphore.acquire(Semaphore .java:55) -locked<0x22c303c8>(aorg.eclipse.core.runtime.internal.adaptor.Semap hore) atorg.eclipse.core.runtime.adaptor.EclipseStarter.updateSplash(EclipseS tarter.java:1251) atorg.eclipse.core.runtime.adaptor.EclipseStarter.setStartLevel(Eclipse Starter.java:1213) atorg.eclipse.core.runtime.adaptor.EclipseStarter.startup(EclipseStarte r.java:288) atorg.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.ja va:175) atsun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethod) atsun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl. java:39) atsun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces sorImpl.java:25) atjava.lang.reflect.Method.invoke(Method.java:597) atorg.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622) atorg.eclipse.equinox.launcher.Main.basicRun(Main.java:577) atorg.eclipse.equinox.launcher.Main.run(Main.java:1410) atorg.eclipse.equinox.launcher.Main.main(Main.java:1386) "VMThread"prio=10tid=0x02bba000nid=0xdb4runnable "VMPeriodicTaskThread"prio=10tid=0x02c0e400nid=0x24acwaitingoncondition JNIglobalreferences:677
分析:
根据提示,有两个线程都用到了ftpClient这个对象作为锁,而且前一个得到锁的要等待后一个需要这个锁的返回结果,造成死锁。这两处分别为:
(1)atorg.apache.commons.net.telnet.TelnetInputStream.__read(TelnetInputStr
eam.java:122)
(2)-locked<0x22942280>(aorg.apache.commons.net.ftp.FTPClient)
atcom.sagemcom.dc.ftp.client.FTPClientFactoryImpl.getClient(FTPClientFa
ctoryImpl.java:35)
-locked<0x228f9310>(ajava.lang.Object)
前者是系统自己用的锁,后者是我代码里面加的。自己代码里面换一个对象做锁就解决了。
总结
jstack在解决问题上还是比较有帮助的,信息简洁有效,其实有很多图形化的分析工具是基于它的。但jstack需要jdk1.6以上的版本才支持。
以上就是本文关于通过jstack分析解决进程死锁问题实例代码的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!