今天部门经理说,看服务器上的java Cpu占用率很高,说要我查一下,定位一下代码,其实他说这个我心里就有底了,因为这个慢的地方代码,是我写的哈哈,好了,回归正题,今天想了想,有没有什么办法可以定位到代码的类和具体行呢,今天搜了搜,自己在这里记录一下。
先准备好测试的代码,这个是测试死锁的,今天主要是记录怎么查询定位问题,所以线程等知识,就不再这记录了
package com.demo.testJvm;
public class TestDeadLock {
private static Object lockA = new Object();
private static Object lockB = new Object();
public static void main(String[] args) {
new Thread(() ->{
synchronized (lockA) {
try {
System.out.println("线程1开始运行========");
Thread.sleep(2000);
} catch (InterruptedException e) {
}
synchronized (lockB) {
System.out.println("线程1运行结束========");
}
}
}).start();
new Thread(() ->{
synchronized (lockB) {
try {
System.out.println("线程2开始运行========");
Thread.sleep(2000);
} catch (InterruptedException e) {
}
synchronized (lockA) {
System.out.println("线程2结束运行========");
}
}
}).start();
System.out.println("主线程运行结束========");
}
}
本地启动
后面不执行了,说明死锁了.
Win+R 输入CMD 在命令行里输入 JPS
接着我们找到我们的项目,TestDeadLock 的Pid为27784
接着我们输入jstack -l 27784
从图中红线出可以找到,对应的代码行号
补充: 如果你本地的cmd 命令 输入 jps 和 jstack 报无法处理的错,你需要配置你的JAVA环境
接下来是在Linux服务器上部署这个Test 项目,去测试CPU占用率过高的问题.
测试CPU占用高的代码
@Component
public class TestCpuTop {
private static ExecutorService executorService = Executors.newFixedThreadPool(5);
@Scheduled(cron = "${scheduled.cron}")
public void testCpu() {
Task task1 = new Task();
Task task2 = new Task();
System.out.println("开始执行了");
executorService.execute(task1);
System.out.println("开始执行了1");
executorService.execute(task2);
}
public static Object lock = new Object();
static class Task implements Runnable {
@Override
public void run() {
synchronized (lock) {
long sum = 0L;
while (true) {
sum += 1;
}
}
}
}
}
linux 命令
top 查看服务所占CPU比例
pid为 17361
top -Hp 17361
执行 jstack 17361|grep -A 10 4cd0,得到线程堆栈信息中 4cd0 这个线程所在行的后面10行,从堆栈中可以发现导致cpu飙高的调 用方法
最后查看对应的堆栈信息找出可能存在问题的代码。