• jstack实战死循环与死锁学习笔记


    一、实战死循环导致CPU飙高

    top -p pid -H

    jstack pid

    printf "%s"  十进制的线程id

    二、创建CUP100%实例(死循环)

    1、创建CpuController

    @RestController
    public class CpuController {
    
        @RequestMapping("/loop")
        public  List<Long> loop(){
            String data = "{"data":[{"partnerid":]}";
            return  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;
        }
    
    }
    getPartneridsFromJson发生死循环

    2.打包
    D:workspacemonitor_tuning>mvn clean package -Dmaven.test.skip

    pom.xml的配置如下
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    	<modelVersion>4.0.0</modelVersion>
    
    	<groupId>com.example</groupId>
    	<artifactId>monitor_tuning</artifactId>
    	<version>0.0.1-SNAPSHOT</version>
    	<packaging>jar</packaging>
    
    	<name>monitor_tuning</name>
    	<description>Demo project for Spring Boot</description>
    
    	<parent>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-parent</artifactId>
    		<version>2.1.1.RELEASE</version>
    		<relativePath/> <!-- lookup parent from repository -->
    	</parent>
    
    	<properties>
    		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    		<java.version>1.8</java.version>
    	</properties>
    
    	<dependencies>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-web</artifactId>
    		</dependency>
    
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-test</artifactId>
    			<scope>test</scope>
    		</dependency>
    
    		<dependency>
    			<groupId>asm</groupId>
    			<artifactId>asm</artifactId>
    			<version>3.3.1</version>
    		</dependency>
    	</dependencies>
    
    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.apache.maven.plugins</groupId>
    				<artifactId>maven-compiler-plugin</artifactId>
    				<version>3.1</version>
    				<!-- compile for Java 1.8 -->
    				<configuration>
    					<source>1.8</source>
    					<target>1.8</target>
    					<encoding>UTF-8</encoding>
    					<compilerArgs>
    						<!-- 过期的方法的警告-->
    						<arg>-Xlint:deprecation</arg>
    					</compilerArgs>
    					<compilerArguments>
    						<!-- 是否输出所有的编译信息(包括类的加载等)-->
    						<!--<verbose />-->
    						<!-- 解决maven命令编译报错,因为rt.jar 和jce.jar在jre的lib下面,不在jdk的lib下面,
                            导致maven找不到(java7以后会出现这个问题),将这2个jar包拷贝到jdk的lib下面估计也好使-->
    						<bootclasspath>${java.home}lib
    t.jar;${java.home}libjce.jar</bootclasspath>
    					</compilerArguments>
    				</configuration>
    			</plugin>
    			<plugin>
    				<groupId>org.springframework.boot</groupId>
    				<artifactId>spring-boot-maven-plugin</artifactId>
    
    			</plugin>
    
    
    		</plugins>
    	</build>
    
    
    </project>  

    端口设置为9080

    3、生成jar完成后,将它放在测试服务器

    nohup java -jar monitor_tuning-0.0.1-SNAPSHOT.jar

     
    四、我这里是将 monitor_tuning以war包的的形式部署到我的测试服务器
    1)打开多个页面调用loop方法
    http://*.*.*.*:7080/monitor_tuning/loop

    2)使用top命令查看cpu的使用
    3、jstack 20738 > 20738.txt
    sz
    20738.txt 下载文件

    4、 打印所有的线程
    top -p 20738 -H

     

     打印946为10进制,结果为3b2

     打开刚才的20738.txt文件

    查找3b2

    这样就定位到了getPartneridsFromJson这个方法。

    三、创建CUP100%实例(死锁)

     创建两个线程,线程1先获得锁1,然后获得锁2; 线程二先获得锁2,然后获得锁1. 然后两个线程造成死锁。

      private Object lock1 = new Object();
        private Object lock2 = new Object();
    
        /**
         * 死锁
         */
        @RequestMapping("/deadlock")
        public  String deadlock(){
            new Thread(()->{
                synchronized (lock1){
                    try {
                        Thread.sleep(1000);
                        synchronized (lock2){
                            System.out.println("Thread1 over");
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
    
            new Thread(()->{
                synchronized (lock2){
                    try {
                        Thread.sleep(1000);
                        synchronized (lock1){
                            System.out.println("Thread2 over");
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
    
            return  "deadlock";
        }
    

      

    jstack 8704 > 8704.txt 8704为tomcat的进程

    将8704.txt拉到底部,可以看到死锁的信息。

    Found one Java-level deadlock:
    =============================
    "Thread-9":
      waiting to lock monitor 0x0000000000eaeb08 (object 0x00000000f6d7abf8, a java.lang.Object),
      which is held by "Thread-8"
    "Thread-8":
      waiting to lock monitor 0x00007f82ac0062c8 (object 0x00000000f6d7ac08, a java.lang.Object),
      which is held by "Thread-9"
    
    Java stack information for the threads listed above:
    ===================================================
    "Thread-9":
    	at com.example.monitor_tuning.chapter2.CpuController.lambda$deadlock$1(CpuController.java:52)
    	- waiting to lock <0x00000000f6d7abf8> (a java.lang.Object)
    	- locked <0x00000000f6d7ac08> (a java.lang.Object)
    	at com.example.monitor_tuning.chapter2.CpuController$$Lambda$389/1326472202.run(Unknown Source)
    	at java.lang.Thread.run(Thread.java:748)
    "Thread-8":
    	at com.example.monitor_tuning.chapter2.CpuController.lambda$deadlock$0(CpuController.java:39)
    	- waiting to lock <0x00000000f6d7ac08> (a java.lang.Object)
    	- locked <0x00000000f6d7abf8> (a java.lang.Object)
    	at com.example.monitor_tuning.chapter2.CpuController$$Lambda$388/1104652864.run(Unknown Source)
    	at java.lang.Thread.run(Thread.java:748)
    
    Found 1 deadlock.
    

      

    
    
  • 相关阅读:
    ES6(严格模式,let&const,箭头函数,解构赋值,字符串扩展方法,Symbol,Set和Map,生成器函数)
    动画实现-微信语音小喇叭样式
    JS与React分别实现倒计时(天时分秒)
    MacOS下如何设置hosts?
    原生JS实现‘点击元素切换背景及字体等’
    mysql数据库设计规范
    如何对 ElasticSearch 集群进行压力测试
    设计实现SAM--无服务器应用模型
    韩立刚计算机网络笔记-第11章 因特网上的音频视频-无线网络
    韩立刚计算机网络笔记-第10章 网络安全
  • 原文地址:https://www.cnblogs.com/linlf03/p/10056339.html
Copyright © 2020-2023  润新知