异常说明
内存泄露: 应该被垃圾回收器回收的对象没有被回收,发生内存泄露了后面就容易发生内存溢出
内存溢出: 有5M的对象要存放到内存,但是内存存满了存放不进去,
OutOfMemoryError: 内存溢出(内存不够)
StackOverflowError
模拟代码
1.内存溢出OutOfMemoryError jmap
代码1
public class OOMTest {
public static void main(String[] args) {
List<Object> list = new ArrayList<>();
while (true) {
list.add(new OOMTest());
}
}
}
代码2
public class OOMTest {
public static void main(String[] args) {
List<Object> list = new ArrayList<>();
while (true) {
list.add(new UserAddDto());
}
}
}
a.任意时刻导出内存信息快照用命令:jmap -dump:format=b,file=heapInfo.dump 13304
b.内存溢出时导出内存信息快照,运行参数添加如下:
-Xmx5m
-Xms5m
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=./heapInfoWhenOutOfMemeory.dump
-XX:+PrintGCDetails
c.dump文件用jvisualvm打开(cmd用命令jvisualvm.exe打开,文件——装入——选择heapInfoWhenOutOfMemeory.dump文件—)
模拟1实例数超出的是类OOMTest,模拟2实例数超出的是类UserAddDto
内存飙升判断是否大量类生成,导出服务堆信息,看哪个类的实例数多,说明这个类的对象被大量创建
2.高CPU jstack
public class HighCPUTest {
public static final int initDadta = 666;
public static UserAddDto userAddDto = new UserAddDto();
private static void compute() {
int a = 1;
int b = 2;
int c;
c = (a + b) * 10;
System.out.println(c);
}
public static void main(String[] args) {
while (true){
compute();
}
}
}
找出高CPU代码位置:
a.top命令获取高CPU的进程id 9326
b.top -p 进程id
c.敲一下大写H,展示这个进程所有的线程 获取CPU高的线程 9327
d.将高CPU的线程pid由十进制转成十六进制246f
e.jstack 9326 | grep -A 10 246f(10表示取10行)
3.死锁 jstack
public class DeadLockTest {
private static Object lock1 = new Object();
private static Object lock2 = new Object();
public static void main(String[] args) {
new Thread(() -> {
synchronized (lock1) {
try {
System.out.println("线程1执行");
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock2) {
try {
System.out.println("线程1结束");
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
new Thread(() -> {
synchronized (lock2) {
try {
System.out.println("线程2执行");
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock1) {
try {
System.out.println("线程2结束");
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
查看死锁代码位置
方法1:jps查看线程id,然后jstack -线程id
方法2:jvisualvm打开,点击这个项目,会提示"检测到死锁 生成一个线程Dump以获取更多信息",点击线程Dump