fastthread使用
前言
关于fastthread的介绍直接看官方首页就行:
- 及时根本原因分析
- 在线线程转储分析
- 出色的UI
- 线程转储分析REST API
- 通用的Java线程转储分析器
支持核心转储分析、hs_err_pid文件分析,这个笔者也不知道,后面再了解下
举个例子
package com.study.fastthread;
import lombok.SneakyThrows;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
public class DeadLockDemon {
@SneakyThrows
public static void main(String[] args) {
DeadLockTask deadLockTask = new DeadLockTask();
//多线程模拟死锁
Thread threadA = new Thread(deadLockTask);
Thread threadB = new Thread(deadLockTask);
threadA.start();
threadB.start();
threadA.join();
}
private static class DeadLockTask implements Runnable {
private Object lockA = new Object();
private Object lockB = new Object();
private AtomicBoolean flag = new AtomicBoolean(false);
@SneakyThrows
@Override
public void run() {
if (flag.compareAndSet(false, true)) {
synchronized (lockA) {
TimeUnit.SECONDS.sleep(2);
synchronized (lockB) {
System.out.println("死锁内部代码");
}
}
} else {
synchronized (lockB) {
TimeUnit.SECONDS.sleep(2);
synchronized (lockA) {
System.out.println("死锁内部代码");
}
}
}
}
}
}
笔者之前使用visual vm,所以打开看看,一目了然,可以dump下来(也可以使用jstack -l <pid>
)使用fastthread看看对比一下。
使用
打开官网首页选择文件即可。
线程计数摘要
线程组
8个GC Task线程,2个Thread线程,可以点进去看看这两个线程:
可以看到就是我们new出来的。
守护 vs 非守护线程
- 守护线程:
可以看到很多RMI、JMX、C1、C2线程,笔者也不是很清楚,搜到一些资料贴在文末。
- 非守护线程:
可以看到new出来的线程、main线程、VM和GC相关的线程都是非守护线程。
死锁
具有相同stack trace的线程
- 看看最多的:
VM和GC相关,没有stack trace
- block的
最后执行的方法
CPU消耗线程
阻塞线程-传递图
GC线程
gc线程数正常
线程堆栈深度
可以看到递归问题
复杂死锁
Finalizer Thread
异常
火焰图
最下面为root,下到上看到调用链,可以点开:
自下而上调用栈树
总结
可以看到,fastthread各方面都比visual vm详细,除了没有展示线程运行时间。 但是有时候多了也不容易发现问题,所以我们需要知道因为线程相关导致的问题有哪些,然后对应去看,比如:
- 某个接口一直没有响应,但是各项资源都充足,可以去看看死锁。
- 所有接口都响应很慢,可以先看看线程计数摘要,看看是不是线程数超标,那部分超标可以看看线程组,再细看下是那部分代码占用了很多可以看看具有相同stack trace的线程,或者直接看最后执行的方法,有时候并不是因为某个线程本身发生了阻塞而是因为其他线程,可以看看阻塞线程-传递图
- CPU飙升,可以看看CPU消耗线程。
- 内存泄漏了,看看GC线程是否正常,Finalizer Thread是否正常。
- 堆栈溢出,可以看看线程栈深度。
- 需要具体的分析可以看看自下而上调用栈树。
相关资料
转载自:https://juejin.cn/post/7202252704977698871