Java栈里面最重要的就是线程了。一般程序发生死循环、死锁、线程Hang住 等问题,我们都需要从栈上去分析原因。
jstack
一般出现CPU过高、线程假死等问题,都可以利用 jstack 命令来讲栈信息导出分析具体原因。 我们先来看一个案例:
- 启动应用
java -jar springboot-jwt-1.0.0.jar &

- 打印栈信息,并生成到一个app.txt文件内
jstack 10802 > app.txt
- 下载
app.txt文件到本地
[lb@centos-linux ~]$ sz app.txt
内容如下:
2021-02-01 06:05:46
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.271-b09 mixed mode):
# `#129 `内部标识号
# daemon 守护线程
# prio=9 优先级
# os_prio=0 系统级优先级
# tid=0x00007fa5a8001000 线程16进制ID
# nid=0x3943 进程16进制ID
"Attach Listener" #129 daemon prio=9 os_prio=0 tid=0x00007fa5a8001000 nid=0x3943 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"DestroyJavaVM" #128 prio=5 os_prio=0 tid=0x00007fa5d8009800 nid=0x2a33 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
# Tomcat
"http-nio-8080-Acceptor" #126 daemon prio=5 os_prio=0 tid=0x00007fa5d8bd8800 nid=0x2ad7 runnable [0x00007fa5970f1000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method)
at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:424)
at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:252)
- locked <0x00000000f9188878> (a java.lang.Object)
at org.apache.tomcat.util.net.NioEndpoint.serverSocketAccept(NioEndpoint.java:469)
at org.apache.tomcat.util.net.NioEndpoint.serverSocketAccept(NioEndpoint.java:71)
at org.apache.tomcat.util.net.Acceptor.run(Acceptor.java:95)
at java.lang.Thread.run(Thread.java:748)
"http-nio-8080-ClientPoller" #125 daemon prio=5 os_prio=0 tid=0x00007fa5d8b42000 nid=0x2ad6 runnable [0x00007fa5971f2000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269)
at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
- locked <0x00000000f9415be8> (a sun.nio.ch.Util$3)
- locked <0x00000000f9415bd8> (a java.util.Collections$UnmodifiableSet)
- locked <0x00000000f9415ac0> (a sun.nio.ch.EPollSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
at org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:709)
at java.lang.Thread.run(Thread.java:748)
"http-nio-8080-exec-10" #124 daemon prio=5 os_prio=0 tid=0x00007fa5d8bc0800 nid=0x2ad5 waiting on condition [0x00007fa5972f3000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000f92c6e08> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:107)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
"http-nio-8080-exec-9" #123 daemon prio=5 os_prio=0 tid=0x00007fa5d8ad7000 nid=0x2ad4 waiting on condition [0x00007fa5973f4000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000f92c6e08> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:107)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
"http-nio-8080-exec-8" #122 daemon prio=5 os_prio=0 tid=0x00007fa5d8ad5000 nid=0x2ad3 waiting on condition [0x00007fa5974f5000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000f92c6e08> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:107)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
"http-nio-8080-exec-7" #121 daemon prio=5 os_prio=0 tid=0x00007fa5d8a43000 nid=0x2ad2 waiting on condition [0x00007fa5975f6000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000f92c6e08> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:107)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
"http-nio-8080-exec-6" #120 daemon prio=5 os_prio=0 tid=0x00007fa5d8a41000 nid=0x2ad1 waiting on condition [0x00007fa5976f7000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000f92c6e08> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:107)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
"http-nio-8080-exec-5" #119 daemon prio=5 os_prio=0 tid=0x00007fa5d8a3f000 nid=0x2ad0 waiting on condition [0x00007fa5977f8000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000f92c6e08> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:107)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
"http-nio-8080-exec-4" #118 daemon prio=5 os_prio=0 tid=0x00007fa5d8999000 nid=0x2acf waiting on condition [0x00007fa5978f9000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000f92c6e08> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:107)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
"http-nio-8080-exec-3" #117 daemon prio=5 os_prio=0 tid=0x00007fa5d8997000 nid=0x2ace waiting on condition [0x00007fa5979fa000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000f92c6e08> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:107)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
"http-nio-8080-exec-2" #116 daemon prio=5 os_prio=0 tid=0x00007fa5d8996000 nid=0x2acd waiting on condition [0x00007fa597afb000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000f92c6e08> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:107)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
"http-nio-8080-exec-1" #115 daemon prio=5 os_prio=0 tid=0x00007fa5d84e2800 nid=0x2acc waiting on condition [0x00007fa597bfc000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000f92c6e08> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:107)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
"http-nio-8080-BlockPoller" #114 daemon prio=5 os_prio=0 tid=0x00007fa5d8af1800 nid=0x2acb runnable [0x00007fa597cfd000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269)
at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
- locked <0x00000000f918cdf8> (a sun.nio.ch.Util$3)
- locked <0x00000000f918cd70> (a java.util.Collections$UnmodifiableSet)
- locked <0x00000000f918c9a8> (a sun.nio.ch.EPollSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
at org.apache.tomcat.util.net.NioBlockingSelector$BlockPoller.run(NioBlockingSelector.java:313)
"container-0" #113 prio=5 os_prio=0 tid=0x00007fa5d8ad0800 nid=0x2aca waiting on condition [0x00007fa597ffe000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at org.apache.catalina.core.StandardServer.await(StandardServer.java:570)
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer$1.run(TomcatWebServer.java:197)
"Catalina-utility-2" #112 prio=1 os_prio=0 tid=0x00007fa5d8acf800 nid=0x2ac9 waiting on condition [0x00007fa5c81f0000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000ffcd9e58> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
"Catalina-utility-1" #111 prio=1 os_prio=0 tid=0x00007fa5d8cd7800 nid=0x2ac8 waiting on condition [0x00007fa5c82f1000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000ffcd9e58> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1088)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
"Service Thread" #7 daemon prio=9 os_prio=0 tid=0x00007fa5d8149800 nid=0x2a3c runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C1 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007fa5d813e800 nid=0x2a3b waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007fa5d813b800 nid=0x2a3a waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007fa5d813a000 nid=0x2a39 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007fa5d8109000 nid=0x2a38 in Object.wait() [0x00007fa5c88f7000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000e358fc40> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
- locked <0x00000000e358fc40> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:216)
"Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007fa5d8104800 nid=0x2a37 in Object.wait() [0x00007fa5c89f8000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000e349aa18> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
- locked <0x00000000e349aa18> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
"VM Thread" os_prio=0 tid=0x00007fa5d80fa800 nid=0x2a36 runnable
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007fa5d801e800 nid=0x2a34 runnable
"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007fa5d8020800 nid=0x2a35 runnable
"VM Periodic Task Thread" os_prio=0 tid=0x00007fa5d814c800 nid=0x2a3d waiting on condition
JNI global references: 1064
配置JVM栈大小
我们来模拟一个栈递归调用深度异常
- 编写测试代码
public class JvmStackRecursionDemo {
private static int count;
private static void counterRecursion(){
count ++ ;
counterRecursion();
}
/**
* JVM args : -Xss1m
*/
public static void main(String[] args) {
try{
counterRecursion();
}catch (Throwable t){
System.err.println("count="+count);
t.printStackTrace();
}
}
}
- 指定JVM参数:
-Xss10m(栈空间为10MB) - 运行测试代码
count=257082
java.lang.StackOverflowError
at com.lb.gc.JvmStackRecursionDemo.counterRecursion(JvmStackRecursionDemo.java:16)
at com.lb.gc.JvmStackRecursionDemo.counterRecursion(JvmStackRecursionDemo.java:16)
at com.lb.gc.JvmStackRecursionDemo.counterRecursion(JvmStackRecursionDemo.java:16)
at com.lb.gc.JvmStackRecursionDemo.counterRecursion(JvmStackRecursionDemo.java:16)
at com.lb.gc.JvmStackRecursionDemo.counterRecursion(JvmStackRecursionDemo.java:16)
at com.lb.gc.JvmStackRecursionDemo.counterRecursion(JvmStackRecursionDemo.java:16)
...
CPU过高如何处理?
基本流程:
- 找出10进制的线程号
top -Hp <应用进程ID>- 转换为16进制
printf "%x" <线程号>jstack > <文件名>导出栈信息,查找线程IDnid
- 测试代码
@RestController
public class JvmStackDeadStackDemo {
@GetMapping("deadLoop")
public String deadLoop()throws Exception{
while (true){
System.err.println("running forever");
}
}
}
- 启动 ( & 代表后台启动 )
java -jar springboot-jwt-1.0.0.jar &
- 执行死循环
curl locahost:8081/deadLoop
- 查看系统进程信息
top
可以看出 3765 这个进程CPU占用率最高

- 查看进程的详细信息
top -Hp 3765
可以看出 3948 这个线程占用率最高

- 将3948转为16进制
printf "%x" 3948

- 导出栈信息
# 查看进程号
[lb@centos-linux ~]$ jps -l
18482 sun.tools.jps.Jps
3765 springboot-jwt-1.0.0.jar
# 生成栈信息
[lb@centos-linux ~]$ jstack 3765 > jstac-3765.txt
[lb@centos-linux ~]$ ls
jstac-3765.txt jstack.txt libs servers soft springboot-jwt-1.0.0.jar
- 查看栈信息,搜索16进制线程号关键字
f6c

nid=0xf6c ,其中0x是补位不用关注
如何排查死锁问题
关于死锁问题很简单,比如2个对象相互持有对方的锁,又想要执行下去, 就会出现死锁。 解决思路:
- 导出栈信息
jstack pid > jstack.txt- 搜索
deadlock关键字
- 编写死锁测试代码
@GetMapping("deadLock")
public String deadLock(){
Object lock1 = new Object();
Object lock2 = new Object();
new Thread(() -> {
// 获取自己的锁
synchronized (lock1){
try {
Thread.sleep(2000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 获取他人的锁
synchronized (lock2){
System.err.println("thread1 try hold lock2");
}
}
},"thread1").start();
new Thread(() -> {
// 获取自己的锁
synchronized (lock2){
try {
Thread.sleep(2000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 获取他人的锁
synchronized (lock1){
System.err.println("thread2 try hold lock1");
}
}
},"thread2").start();
return "deadLock";
}
- 启动应用
java -jar springboot-jwt-1.0.0.jar &
- 执行死锁代码
curl localhost:8081/deadLock
# 得到响应结果
deadLock
- 导出栈信息
jstack 18899 > deadlock.txt
- 查找
deadlock关键字

本文介绍Java栈的重要性和使用jstack工具分析线程状态的方法。通过实例演示如何定位CPU过高、死循环及死锁等问题,并提供测试代码帮助理解。
922

被折叠的 条评论
为什么被折叠?



