使用top命令、dump文件定位问题
1.背景
定位java应用出问题的代码块
2.一个demo
一个springboot创建的demo
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DemoController {
/**
* 测试demo
*
* @return
*/
@GetMapping("/test")
public Object topDemo() {
for (int i = 0; i < 100000; i += 2) {
try {
System.out.println(" print" + i);
Thread.sleep(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "test";
}
/**
* 调试
*
* @return
*/
@GetMapping("/test2")
public Object topDemo1() {
return "ok";
}
}
部署
![](https://i-blog.csdnimg.cn/blog_migrate/454af89c79d4d2a8889c13e6601b3957.png)
打开浏览器访问:
![](https://i-blog.csdnimg.cn/blog_migrate/1b560eacdb8e6cc2ab726b9e97de07b6.png)
![](https://i-blog.csdnimg.cn/blog_migrate/afe07d66072b23ac5029b14ad39f3cb9.png)
访问test接口是一直处于等待状态。
3.定位问题
连接到linux服务器 。
打开 Linux 服务器,敲 top 命令查看消耗 CPU 中的 Java 进程,通过观察该进程在操作系统中消耗 CPU 不高。
![](https://i-blog.csdnimg.cn/blog_migrate/fab700825b6836ab7a8a5dbb8fd41cfd.png)
使用 top -p PID
![](https://i-blog.csdnimg.cn/blog_migrate/403f50169c6a3b76e6e0633a90d31fc9.png)
使用 jstack 命令进行,打出 dump 信息
![](https://i-blog.csdnimg.cn/blog_migrate/70e33672cf277173b6b2105cb780ac71.png)
使用 top -H -p 8819 .仔细观察一下,发现 9809这个线程 偶尔会 跳到第一行.
![](https://i-blog.csdnimg.cn/blog_migrate/49f5aa2ad821d109da89c8a963440b6f.png)
将线程号 9809 转换成16进制即为2651 . (可以敲命令 printf "%x\n" 9809 输出16进制)
vim javademo.dump 打开dump文件
/2651 搜索2651
可以看到 topDemo()这个方法。
![](https://i-blog.csdnimg.cn/blog_migrate/fbe432b6c7cddc9f3ee784337491bf88.png)
"http-nio-8080-exec-5" 线程名称
井20 线程编号
daemon 线程的类型
prio=5 线程的优先级别
os_prio=0 系统级别的线程优先级
tid=0x00007f5270008800 线程ID
nid=0x2651 native线程的id
waiting on condition 线程当前的状态
[0x00007f5266bf4000] 线程占用内存地址
java.lang.Thread.State: TIMED_WAITING (sleeping)
![](https://i-blog.csdnimg.cn/blog_migrate/23bf3f16f796ef0ea6bf4e636001d783.png)
![](https://i-blog.csdnimg.cn/blog_migrate/f9cbf22927b94421c25dbbcbf6a36db5.png)
这样就定位到了问题代码。