JVM死锁、cpu飙高、内存溢出如何定位

  • 如何定位死锁 
     
    命令格式:
    jstack {pid} > aa.txt               // 获取当前pid所有的线程信息,并输出到aa.txt文件内
  1. 创建项目 
    线程死锁代码
    public class LockController {
    
        private Object lock1 = new Object();
        private Object lock2 = new Object();
    
        /**
         * 死锁
         * */
        @RequestMapping("/deadlock")
        public String testLock(){
            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";
        }
    }
    启动项目并访问
  2. 导出线程信息
    // 查看当前java进程和PID
    jps
    // 获取当前PID的线程信息并输出到cc.txt文件 
    jstack 22364 > cc.txt
    
  3. 分析导出文件
    打开cc.txt文件,搜索: deadlock

     
     
  • 如何定位cpu飙高
  1. 创建项目 
    @RestController
    public class CpuController {
    
        // cpu飙高代码
        @GetMapping("/cpu")
        public String indexCpu(){
            boolean fl = true;
            while (fl){
    
            }
            return "...................................";
        }
    }
    

    启动项目(放到单独的服务器测试)
  2. 导出cpu信息 
    // 1、查询服务器中cpu飙高程序的pid
    top
    // 2、根据程序pid导出所有线程信息到aa.txt
    jstack {pid} > aa.txt
    // 3、根据程序pid查看其cpu飙高的线程及对应的tid
    ps -mp {pid} -o THREAD,tid,time
    // 4、将tid转成16进制在aa.txt中搜索对应线程信息
    
    根据第3步获取的cpu飙高的线程对应的tid(十进制)转成十六进制,
    再将十六进制的值在aa.txt文件中搜索,查看cpu飙高线程对应的执行方法。
     
  • 如何定位内存溢出、泄露 
     
     内存溢出: JVM没有足够的内存供程序使用。
     内存泄漏: 创建的对象无法被回收。
  1. 创建项目 
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.UUID;
     
    /**
     * @author xiaobo
     * @Description MemoryController
     * @createTime 2020-01-11 22:31
     */
    @RestController
    public class MemoryController {
        public List<User> userList = new ArrayList<User>();
        public List<Class<?>>  classList = new ArrayList<Class<?>>();
        /**
         *  显示堆空间内存溢出
         *  -Xmx32m -Xms32m  提前设置堆的初始值和最大值为32m
         */
        @GetMapping("/heap")
        public void heap(){
            int i = 0;
            while(true){
                userList.add(new User(1, UUID.randomUUID().toString()));
            }
        }
     
        /**
         * 显示非堆(Metaspace)空间内存溢出
         * -XX:MetaspaceSize=32M -XX:MaxMetaspaceSize=32M  提前设置MetaspaceSize为32m
         */
        @GetMapping("/noheap")
        public String noheap() {
            while(true) {
                classList.addAll(Metaspace.createClasses());
            }
        }
    }

     

  2. 配置启动参数  
    // 表示当发生内存溢出,  则将内存信息输出到d:\heapdump.dump 文件
    -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:\heapdump.dump  
    
    如图:
  3. 使用jvisualvm工具分析导 
    双击'jvisualvm.exe'-->'文件'-->'装入'-->选择导出的内存文件 

      
     点击分析使用内存较高的对象,分析使用的类和方法

  4.  
     
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值