通过jstack分析解决进程死锁问题实例代码
刚才用jstack解决了一个进程死锁的问题——其实早就解决了,也知道原因,只是一直没找到死锁的位置,不太甘心而已。
流程大致如下:
(0)环境要求,jdk1.6及以上
(1)先找到进程的pid,windows下,打开进程管理器,按照名字排序,可以找到叫做javaw.exe的进程(java虚拟机进程一律叫做javaw.exe),要找出哪个是你的进程,记住当前进程列表,然后重启你的进程,pid刷新过的那个即是你的进程。
(2)在cmd下运行:jstack pid,jstack会在console上打出一系列信息
(3)分析上述信息
实例:
我这个问题的的jstack信息如下:
c:\documents and settings\user>jstack 6652 2012-06-07 21:32:02 full thread dump java hotspot(tm) client vm (16.3-b01 mixed mode, sharing): "thread-1" daemon prio=6 tid=0x03010c00 nid=0xcdc waiting for monitor entry [0x0 339f000] java.lang.thread.state: blocked (on object monitor) at org.apache.commons.net.telnet.telnetinputstream.__read(telnetinputstr eam.java:122) - waiting to lock <0x22942280> (a org.apache.commons.net.ftp.ftpclient) at org.apache.commons.net.telnet.telnetinputstream.run(telnetinputstream .java:535) at java.lang.thread.run(thread.java:619) "framework event dispatcher" daemon prio=6 tid=0x03010400 nid=0x998 in object.wa it() [0x0334f000] java.lang.thread.state: waiting (on object monitor) at java.lang.object.wait(native method) - waiting on <0x228fa800> (a org.eclipse.osgi.framework.eventmgr.eventma nager$eventthread) at java.lang.object.wait(object.java:485) at org.eclipse.osgi.framework.eventmgr.eventmanager$eventthread.getnexte vent(eventmanager.java:400) - locked <0x228fa800> (a org.eclipse.osgi.framework.eventmgr.eventmanage r$eventthread) at org.eclipse.osgi.framework.eventmgr.eventmanager$eventthread.run(even tmanager.java:336) "start level event dispatcher" daemon prio=6 tid=0x02fcf400 nid=0x2638 in object .wait() [0x032de000] java.lang.thread.state: waiting (on object monitor) at java.lang.object.wait(native method) - waiting on <0x2295db48> (a [i) at java.lang.object.wait(object.java:485) at org.apache.commons.net.telnet.telnetinputstream.read(telnetinputstrea m.java:339) - locked <0x2295db48> (a [i) at org.apache.commons.net.telnet.telnetinputstream.read(telnetinputstrea m.java:466) at java.io.bufferedinputstream.read1(bufferedinputstream.java:256) at java.io.bufferedinputstream.read(bufferedinputstream.java:317) - locked <0x2295fe18> (a java.io.bufferedinputstream) at sun.nio.cs.streamdecoder.readbytes(streamdecoder.java:264) at sun.nio.cs.streamdecoder.implread(streamdecoder.java:306) at sun.nio.cs.streamdecoder.read(streamdecoder.java:158) - locked <0x22961f88> (a java.io.inputstreamreader) at java.io.inputstreamreader.read(inputstreamreader.java:167) at java.io.bufferedreader.fill(bufferedreader.java:136) at java.io.bufferedreader.readline(bufferedreader.java:299) - locked <0x22961f88> (a java.io.inputstreamreader) at java.io.bufferedreader.readline(bufferedreader.java:362) at org.apache.commons.net.ftp.ftp.__getreply(ftp.java:264) at org.apache.commons.net.ftp.ftp._connectaction_(ftp.java:335) at org.apache.commons.net.ftp.ftpclient._connectaction_(ftpclient.java:5 50) at org.apache.commons.net.socketclient.connect(socketclient.java:163) at com.mycompany.dc.ftp.client.ftpclientimpl.connect(ftpclientimpl.java:7 5) - locked <0x22942280> (a org.apache.commons.net.ftp.ftpclient) at com.mycompany.dc.ftp.client.ftpclientfactoryimpl.getclient(ftpclientfa ctoryimpl.java:35) - locked <0x228f9310> (a java.lang.object) at ftpclienttest.activator.start(activator.java:43) at org.eclipse.osgi.framework.internal.core.bundlecontextimpl$1.run(bund lecontextimpl.java:711) at java.security.accesscontroller.doprivileged(native method) at org.eclipse.osgi.framework.internal.core.bundlecontextimpl.startactiv ator(bundlecontextimpl.java:702) at org.eclipse.osgi.framework.internal.core.bundlecontextimpl.start(bund lecontextimpl.java:683) at org.eclipse.osgi.framework.internal.core.bundlehost.startworker(bundl ehost.java:381) at org.eclipse.osgi.framework.internal.core.abstractbundle.resume(abstra ctbundle.java:389) at org.eclipse.osgi.framework.internal.core.framework.resumebundle(frame work.java:1131) at org.eclipse.osgi.framework.internal.core.startlevelmanager.resumebund les(startlevelmanager.java:559) at org.eclipse.osgi.framework.internal.core.startlevelmanager.resumebund les(startlevelmanager.java:544) at org.eclipse.osgi.framework.internal.core.startlevelmanager.incfwsl(st artlevelmanager.java:457) at org.eclipse.osgi.framework.internal.core.startlevelmanager.dosetstart level(startlevelmanager.java:243) - locked <0x27e68d70> (a java.lang.object) at org.eclipse.osgi.framework.internal.core.startlevelmanager.dispatchev ent(startlevelmanager.java:438) at org.eclipse.osgi.framework.internal.core.startlevelmanager.dispatchev ent(startlevelmanager.java:1) at org.eclipse.osgi.framework.eventmgr.eventmanager.dispatchevent(eventm anager.java:230) at org.eclipse.osgi.framework.eventmgr.eventmanager$eventthread.run(even tmanager.java:340) "framework active thread" prio=6 tid=0x02ff1800 nid=0x1fbc in object.wait() [0x0 328f000] java.lang.thread.state: timed_waiting (on object monitor) at java.lang.object.wait(native method) - waiting on <0x27e65770> (a org.eclipse.osgi.framework.internal.core.fr amework) at org.eclipse.osgi.framework.internal.core.framework.run(framework.java :1817) - locked <0x27e65770> (a org.eclipse.osgi.framework.internal.core.framew ork) at java.lang.thread.run(thread.java:619) "osgi console" prio=6 tid=0x03005400 nid=0x225c waiting on condition [0x0323f000 ] java.lang.thread.state: timed_waiting (sleeping) at java.lang.thread.sleep(native method) at org.eclipse.osgi.framework.internal.core.frameworkconsole.runconsole( frameworkconsole.java:125) at org.eclipse.osgi.framework.internal.core.frameworkconsole.run(framewo rkconsole.java:104) at java.lang.thread.run(thread.java:619) "low memory detector" daemon prio=6 tid=0x02c09800 nid=0x1d68 runnable [0x000000 00] java.lang.thread.state: runnable "compilerthread0" daemon prio=10 tid=0x02c03000 nid=0x24c4 waiting on condition [0x00000000] java.lang.thread.state: runnable "attach listener" daemon prio=10 tid=0x02c01800 nid=0x1138 waiting on condition [0x00000000] java.lang.thread.state: runnable "signal dispatcher" daemon prio=10 tid=0x02c20c00 nid=0x18ac runnable [0x0000000 0] java.lang.thread.state: runnable "finalizer" daemon prio=8 tid=0x02bc0400 nid=0x11ac in object.wait() [0x02d8f000 ] java.lang.thread.state: waiting (on object monitor) at java.lang.object.wait(native method) - waiting on <0x27d5e5c8> (a java.lang.ref.referencequeue$lock) at java.lang.ref.referencequeue.remove(referencequeue.java:118) - locked <0x27d5e5c8> (a java.lang.ref.referencequeue$lock) at java.lang.ref.referencequeue.remove(referencequeue.java:134) at java.lang.ref.finalizer$finalizerthread.run(finalizer.java:159) "reference handler" daemon prio=10 tid=0x02bbb800 nid=0x9cc in object.wait() [0x 02d3f000] java.lang.thread.state: waiting (on object monitor) at java.lang.object.wait(native method) - waiting on <0x27d5e650> (a java.lang.ref.reference$lock) at java.lang.object.wait(object.java:485) at java.lang.ref.reference$referencehandler.run(reference.java:116) - locked <0x27d5e650> (a java.lang.ref.reference$lock) "main" prio=6 tid=0x008a6c00 nid=0x22ec in object.wait() [0x0098f000] java.lang.thread.state: timed_waiting (on object monitor) at java.lang.object.wait(native method) - waiting on <0x22c303c8> (a org.eclipse.core.runtime.internal.adaptor.s emaphore) at org.eclipse.core.runtime.internal.adaptor.semaphore.acquire(semaphore .java:55) - locked <0x22c303c8> (a org.eclipse.core.runtime.internal.adaptor.semap hore) at org.eclipse.core.runtime.adaptor.eclipsestarter.updatesplash(eclipses tarter.java:1251) at org.eclipse.core.runtime.adaptor.eclipsestarter.setstartlevel(eclipse starter.java:1213) at org.eclipse.core.runtime.adaptor.eclipsestarter.startup(eclipsestarte r.java:288) at org.eclipse.core.runtime.adaptor.eclipsestarter.run(eclipsestarter.ja va:175) at sun.reflect.nativemethodaccessorimpl.invoke0(native method) at sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl. java:39) at sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodacces sorimpl.java:25) at java.lang.reflect.method.invoke(method.java:597) at org.eclipse.equinox.launcher.main.invokeframework(main.java:622) at org.eclipse.equinox.launcher.main.basicrun(main.java:577) at org.eclipse.equinox.launcher.main.run(main.java:1410) at org.eclipse.equinox.launcher.main.main(main.java:1386) "vm thread" prio=10 tid=0x02bba000 nid=0xdb4 runnable "vm periodic task thread" prio=10 tid=0x02c0e400 nid=0x24ac waiting on condition jni global references: 677
分析:
根据提示,有两个线程都用到了ftpclient这个对象作为锁,而且前一个得到锁的要等待后一个需要这个锁的返回结果,造成死锁。这两处分别为:
(1) at org.apache.commons.net.telnet.telnetinputstream.__read(telnetinputstr
eam.java:122)
(2) - locked <0x22942280> (a org.apache.commons.net.ftp.ftpclient)
at com.sagemcom.dc.ftp.client.ftpclientfactoryimpl.getclient(ftpclientfa
ctoryimpl.java:35)
- locked <0x228f9310> (a java.lang.object)
前者是系统自己用的锁,后者是我代码里面加的。自己代码里面换一个对象做锁就解决了。
总结
jstack在解决问题上还是比较有帮助的,信息简洁有效,其实有很多图形化的分析工具是基于它的。但jstack需要jdk1.6以上的版本才支持。
以上就是本文关于通过jstack分析解决进程死锁问题实例代码的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!