JDK命令行监控工具

JDK命令行监控工具

jstat查看JVM统计信息

jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
<option> gc、gcutil查看GC信息,class查看类加载信息,......
<vmid> 通过jps查看进程的进程号
[<interval> [<count>]] 每隔interval毫秒执行一次,一共执行count次

内存溢出

@RestController
public class MemoryController {
    private List<UserInfo> userInfoList = new ArrayList<>();
    /**
     * 堆溢出
     * 最大内存和最小内存都是32M
     * -Xmx32M -Xms32M
     * [@return](https://learnku.com/users/31554)
     */
    @GetMapping("/heap")
    public String heap() {
        int i = 0;
        while (true) {
            userInfoList.add(new UserInfo(i++, UUID.randomUUID().toString()));
        }
    }
}

如何导出内存映象文件

  1. 内存溢出自动导出

    -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=目录
    

    当发生内存溢出时,内存映象文件就会被导出到设置的目录所在位置

  2. 使用jmap命令手动导出

    jmap -dump:format=b,file=/自己的目录/heap.hprof 5021
    

MAT分析内存溢出

mat下载地址:https://www.eclipse.org/mat/downloads.php,找到对应的JDK版本

jstack死循环与死锁

用法

jstack [-l] <pid>

java中线程状态

NEW: 线程还没有启动

RUNNABLE: 线程已经在JVM中执行

BLOCKED: 正在等待一把锁

WAITING: 等待另一个线程做特定操作

TIMED_WAITING: 有限时间的等待

TERMINATED: 线程已经退出了

死循环情况

@RestController
public class CpuController {
    /**
     * 在浏览器上多开几个窗口来访问这个接口
     */
    @GetMapping("/loop")
    public String loop() {
        while (true) {
            if (false) {
                break;
            }
        }
        return "";
    }
}
  1. 使用top命令可以查到是哪个进程CPU使用率最高

  2. 使用jstack命令将线程栈打印出来

    jstack 2350 > 2350.txt
    

    查看2350这个进程的所有线程

    top -p 2350 -H
    

    找到使用率较高的线程pid,将其转换成十六进制,因为线程栈中的线程ID是十六进制

    转换如下,假设找到PID是2370

    printf "%x" 2370 # 结果为 942
    

    然后去线程栈中找线程ID为942的信息,从下面可以定位到com.lizhencheng.demo.CpuController.loop(CpuController.java:17)

    "http-nio-8080-exec-3" #15 daemon prio=5 os_prio=0 tid=0x00007f0a48b23000 nid=0x942 runnable [0x00007f0a2456f000]
       java.lang.Thread.State: RUNNABLE
    	at com.lizhencheng.demo.CpuController.loop(CpuController.java:17)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:498)
    	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
    	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
    	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)
    	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879)
    	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793)
    

死锁情况

@RestController
public class CpuController {
    public static Object lock1 = new Object();
    public static Object lock2 = new Object();
    @GetMapping("/deadLock")
    public String deadLock() {
        new Thread(()-> {
            synchronized (lock1) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lock2) {

                }
            }
        }).start();
        new Thread(()->{
            synchronized (lock2) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lock1) {

                }
            }
        }).start();
        return "";
    }
}

导出对应的线程栈信息,在最小面有一个死锁信息

Found one Java-level deadlock:
=============================
"Thread-11":
  waiting to lock monitor 0x00007fb91a1320a8 (object 0x00000007be9d9ba0, a java.lang.Object),
  which is held by "Thread-10"
"Thread-10":
  waiting to lock monitor 0x00007fb91a12d508 (object 0x00000007be9d9b90, a java.lang.Object),
  which is held by "Thread-11"

Java stack information for the threads listed above:
===================================================
"Thread-11":
	at org.example.CpuController.lambda$deadLock$1(CpuController.java:43)
	- waiting to lock <0x00000007be9d9ba0> (a java.lang.Object)
	- locked <0x00000007be9d9b90> (a java.lang.Object)
	at org.example.CpuController$$Lambda$561/526070727.run(Unknown Source)
	at java.lang.Thread.run(Thread.java:748)
"Thread-10":
	at org.example.CpuController.lambda$deadLock$0(CpuController.java:31)
	- waiting to lock <0x00000007be9d9b90> (a java.lang.Object)
	- locked <0x00000007be9d9ba0> (a java.lang.Object)
	at org.example.CpuController$$Lambda$560/1644231291.run(Unknown Source)
	at java.lang.Thread.run(Thread.java:748)

Found 1 deadlock.
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值