用jstack工具分析java程序

最近做项目时遇到了一个问题,我的多个采集线程中,有一个线程经常挂起,线程并没有死掉,但是一直采集不到数据,为了解决这个问题,用到了jstack。

首先查找到java进程的pid,ps -ef|grep java

然后输入jstack pid

核心输出为:

"MSG_RECEIVE_THREAD" prio=10 tid=0x00007fd95034b000 nid=0x2db5 runnable [0x00007fd9d0c26000]
   java.lang.Thread.State: RUNNABLE
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(SocketInputStream.java:152)
    at java.net.SocketInputStream.read(SocketInputStream.java:122)
    at com.ibm.mq.jmqi.remote.internal.RemoteTCPConnection.receive(RemoteTCPConnection.java:1343)
    at com.ibm.mq.jmqi.remote.internal.system.RemoteConnection.receiveTSH(RemoteConnection.java:2834)
    at com.ibm.mq.jmqi.remote.internal.system.RemoteConnection.initSess(RemoteConnection.java:1428)
    at com.ibm.mq.jmqi.remote.internal.system.RemoteConnection.connect(RemoteConnection.java:1106)
    - locked <0x00000000e7d97f18> (a com.ibm.mq.jmqi.remote.internal.system.RemoteConnection$ConnectionMutex)
    at com.ibm.mq.jmqi.remote.internal.system.RemoteConnectionPool.getConnection(RemoteConnectionPool.java:349)
    at com.ibm.mq.jmqi.remote.internal.RemoteFAP.jmqiConnect(RemoteFAP.java:1511)
    at com.ibm.mq.MQSESSION.MQCONNX_j(MQSESSION.java:915)
    at com.ibm.mq.MQManagedConnectionJ11.<init>(MQManagedConnectionJ11.java:226)
    at com.ibm.mq.MQClientManagedConnectionFactoryJ11._createManagedConnection(MQClientManagedConnectionFactoryJ11.java:505)
    at com.ibm.mq.MQClientManagedConnectionFactoryJ11.createManagedConnection(MQClientManagedConnectionFactoryJ11.java:547)
    at com.ibm.mq.StoredManagedConnection.<init>(StoredManagedConnection.java:95)
    at com.ibm.mq.MQSimpleConnectionManager.allocateConnection(MQSimpleConnectionManager.java:182)
    at com.ibm.mq.MQQueueManagerFactory.obtainBaseMQQueueManager(MQQueueManagerFactory.java:869)
    at com.ibm.mq.MQQueueManagerFactory.procure(MQQueueManagerFactory.java:761)
    at com.ibm.mq.MQQueueManagerFactory.constructQueueManager(MQQueueManagerFactory.java:712)
    at com.ibm.mq.MQQueueManagerFactory.createQueueManager(MQQueueManagerFactory.java:171)
    at com.ibm.mq.MQQueueManager.<init>(MQQueueManager.java:603)
    at com.wisdombud.unicom.monitor.listener.MessageByMQ.<init>(MessageByMQ.java:48)
    at com.wisdombud.unicom.monitor.listener.CollectMain$14.run(CollectMain.java:257)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

可以看到,线程是在运行的,不过挂在

java.net.SocketInputStream.socketRead0


通过这句话,可以找到问题的原因,因为IBM的某一个产品发生了问题。

如果没有jstack,就不知道应该如何处理了。

jstack的基本用法:

命令格式: 
jstack [ option ] pid 
基本参数: 
-F当’jstack [-l] pid’没有相应的时候强制打印栈信息 
-l长列表. 打印关于锁的附加信息,例如属于java.util.concurrent的ownable synchronizers列表. 
-m打印java和native c/c++框架的所有栈信息. 
-h | -help打印帮助信息 
pid 需要被打印配置信息的java进程id,可以用jps查询. 

具体用法 
jstack -l 进程ID 


另外,更多内容请参考:
http://www.blogjava.net/jzone/articles/303979.html
原文地址:https://www.cnblogs.com/wardensky/p/4135527.html