欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-03-09 12:00:47
...
  • 如何定位死锁 
     
    命令格式:
    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
    JVM死锁、cpu飙高、内存溢出如何定位
     
     
  • 如何定位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  
    
    如图:
    JVM死锁、cpu飙高、内存溢出如何定位
  3. 使用jvisualvm工具分析导 
    双击'jvisualvm.exe'-->'文件'-->'装入'-->选择导出的内存文件 
    JVM死锁、cpu飙高、内存溢出如何定位
      
     点击分析使用内存较高的对象,分析使用的类和方法
    JVM死锁、cpu飙高、内存溢出如何定位

  4.  
     
相关标签: 2020