线程堆栈信息以及解决的问题
1、线程堆栈的信息都包含:
线程的名字,ID,线程的数量等。
线程的运行状态,锁的状态(锁被哪个线程持有,哪个线程再等待锁等)。
调用堆栈(函数的调用层次关系)。调用堆栈包含完整的类名,执行的方法,源代* 码的行数。具体打印出的堆栈信息依赖于你的系统的复杂程度。
2、通过线程堆栈可以解决的问题
无缘无故CPU过高
系统挂起,无响应
系统运行越来越慢(资源争用或者锁竞争)
线程死锁问题
由于线程数量太多导致系统失败(如无法创建线程等)。
如何输出线程堆栈
1、如果获取堆栈日志
JVM虚拟机提供了线程转储的后门,通过后门可以将线程堆栈打印出来,通过这个后门向指定的Java进程发送一个QUIT信号,Java虚拟机收到信号以后就会打印出进程的堆栈信息。一般我们会将日志信息重定向到文件中。
jstack [option] pid >> jstack.info
jstack命令使用如下:
jstack [option] pid
--参数
1. -F 强制打印堆栈
2. -m 打印java 和 native(C++) 堆栈信息
3. -l 打印额外的信息,包括锁信息
要打印堆栈日志,首先要获取java应用的进程号:
命令一:jps
命令二:ps -ef | grep java
解读线程堆栈
1、堆栈日志
下面是某个线程的堆栈日志:
"com.sankuai.sjst.scm.purchase.service.order.OrderReadThriftService-7-thread-3" #214 daemon prio=5 os_prio=0 tid=0x00007fd406b5b000 nid=0x7a4c waiting for monitor entry [0x00007fd30fffc000]
java.lang.Thread.State: BLOCKED (on object monitor)
at java.io.PrintStream.println(PrintStream.java:805)
- waiting to lock <0x00000000c3b916f8> (a java.io.PrintStream)
at org.apache.ibatis.logging.stdout.StdOutImpl.trace(StdOutImpl.java:50)
at org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:145)
at org.apache.ibatis.logging.jdbc.ResultSetLogger.printColumnValues(ResultSetLogger.java:123)
at org.apache.ibatis.logging.jdbc.ResultSetLogger.invoke(ResultSetLogger.java:78)
at com.sun.proxy.$Proxy111.next(Unknown Source)
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValuesForSimpleResultMap(DefaultResultSetHandler.java:292)
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValues(DefaultResultSetHandler.java:269)
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSet(DefaultResultSetHandler.java:239)
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSets(DefaultResultSetHandler.java:153)
at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:60)
at org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:73)
at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:60)
at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:267)
at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:137)
at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:96)
at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:77)
at org.apache.ibatis.session.defa