work hard work smart

专注于Java后端开发。 不断总结,举一反三。
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

一、实战死循环导致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:\workspace\monitor_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\rt.jar;${java.home}\lib\jce.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.