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()));
}
}
}
如何导出内存映象文件
-
内存溢出自动导出
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=目录
当发生内存溢出时,内存映象文件就会被导出到设置的目录所在位置
-
使用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 "";
}
}
-
使用top命令可以查到是哪个进程CPU使用率最高
-
使用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.