Linux环境下死循环、死锁问题定位

代码准备 死循环

import java.util.ArrayList;
import java.util.List;
/**
 * @author Kiand
 * @date 2022/9/18 19:04
 */
public class dieForTest {
    public static void main(String[] args) {
        String data = "{\"data\":[{\"partnerid\"},{\"partnerid\"},{\"partnerid\"}]}";
        getPartneridsFromJson(data);
    }
    public static List<Long> getPartneridsFromJson(String data){
//        {\"data\":[{\"partnerid\":982,\"count\":\"10000\",\"cityid\":\"11\"},{\"partnerid\":983,\"count\":\"10000\",\"cityid\":\"11\"},{\"partnerid\":984,\"count\":\"10000\",\"cityid\":\"11\"}]}
        //上面是正常的数据
        List<Long> list = new ArrayList<Long>(2);
        if(data == null || data.length() <= 0){
            return list;
        }
        int datapos = data.indexOf("data");
        if(datapos < 0){
            return list;
        }
        int leftBracket = data.indexOf("[",datapos);
        int rightBracket= data.indexOf("]",datapos);
        if(leftBracket < 0 || rightBracket < 0){
            return list;
        }
        String partners = data.substring(leftBracket+1,rightBracket);
        if(partners == null || partners.length() <= 0){
            return list;
        }
        while(partners!=null && partners.length() > 0){
            int idpos = partners.indexOf("partnerid");
            if(idpos < 0){
                break;
            }
            int colonpos = partners.indexOf(":",idpos);
            int commapos = partners.indexOf(",",idpos);
            if(colonpos < 0 || commapos < 0){
//                partners = partners.substring(idpos+"partnerid".length());//1
                continue;
            }
            String pid = partners.substring(colonpos+1,commapos);
            if(pid == null || pid.length() <= 0){
//                partners = partners.substring(idpos+"partnerid".length());//2
                continue;
            }
            try{
                list.add(Long.parseLong(pid));
            }catch(Exception e){
                //do nothing
            }
            partners = partners.substring(commapos);
        }
        return list;
    }
}

部署

普通类打 jar 包步骤

图片

图片

图片

图片图片

后面把 jar 包丢到 linux 中并启动

1.访问死循环方法对应的 url 地址执行死循环代码,top 查看运行的 jar 的进程 ID

图片

可以发现44587这个线程使用cpu达到了98.7

2.使用命令 实验 jstack 获取对应进程的线程堆栈信息,下载到本地查看

jstack 44587 >44587.txt

3.top -p 45587 -H 查看进程中cpu利用率最高的线程ID记录下来在jstack导出的文件中查看对应信息

图片

4.使用printf “%x” 44588 转化为16进制然后在jstack导出的文件中查找对应线程ID的信息

图片

5.通过在jstack导出的文件中查看这个线程的方法栈信息可以确定到运行的方法,定位到问题所在,分析代码是否出现了死循环或者是其他原因。

图片

代码准备 死锁

import java.util.concurrent.locks.ReentrantLock;

/**
 * @author Kiand
 * @date 2022/9/19 2:03
 */
public class DieLockTest {
    static ReentrantLock lock1 = new ReentrantLock();
    static ReentrantLock lock2 = new ReentrantLock();
    public static void main(String[] args) {
        deadlock();
    }
    /**
     * 死锁
     * */
    public static String deadlock(){
        new Thread(()->{
            synchronized(lock1) {
                try {Thread.sleep(1000);}catch(Exception e) {}
                synchronized(lock2) {
                    System.out.println("Thread1 over");
                }
            }
        }) .start();
        new Thread(()->{
            synchronized(lock2) {
                try {Thread.sleep(1000);}catch(Exception e) {}
                synchronized(lock1) {
                    System.out.println("Thread2 over");
                }
            }
        }) .start();
        return "deadlock";
    }

}

1.访问该路径执行这段代码

2.jps查看对应java进程信息

图片

3.jstack 并导出查看

图片

4.根据jstack导出的文件,查看发生死锁的两个线程的详细信息记录。可以很清楚的定位死锁的位置

图片

总结

当发现服务器CPU负载利用率很高时,分析可能出现了死循环或者死锁,通过工具来分析定位问题所在。

死循环:

1、用top查看cpu利用率最高的进程,并用jstack将其进程信息文件导出,

2、用top -p pid -H 查看进程中cpu占用率高的线程,在jstack文件中查询该线程的方法栈信息以定位到问题代码。

死锁:

1、jstack导出进程信息后,查看出现死锁的线程,

2、定位线程中出现死锁的方法,重新设计该段代码排除掉死锁。

补充:导致CPU负载变高的还有其他的原因如频繁的磁盘IO导致进程阻塞,导致CPU利用率飙高的原因也有可能是频繁的GC,具体问题具体解决,都可以使用工具来定位到问题所在。


谢谢关注!!!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值