前置启动程序
事先启动一个web应用程序,用jps查看其进程id,接着用各种jdk自带命令优化应用
1).Jmap 查看内存信息
此命令可以用来查看内存信息,实例个数以及占用内存大小
jmap -histo 130794 > jmap.txt
打开jmap.txt,文件内容如下:
num:序号
instances:实例数量
bytes:占用空间大小
class name:类名称,[C is a char[],[S is a short[],[I is a int[],[B is a byte[],[[I is a int[][]
jmap 查看堆信息
jmap -heap 130794 > jmapHeap.txt
堆内存dump
windows下:
jmap ‐dump:format=b,file=common.hprof 130794
linux下:
jmap -dump:format=b,file=common.dat 130794
用jvisualvm命令工具导入该dump文件分析
cmd中输入jvisualvm来打开工具
点击左上角的文件->装入->堆文件->选择刚才导出的common.dat文件,如下图
也可以设置内存溢出自动导出dump文件(内存很大的时候,可能会导不出来)
如下面的这个代码,在运行的时候,如果OOM了,可以在D盘下找到当时OOM的dump快照文件信息进行导入分析,文件后缀设置dump、dat、hprof都可以:
1. -XX:+HeapDumpOnOutOfMemoryError
2. -XX:HeapDumpPath=./ (路径)
package com.tuling.jvm;
import java.util.ArrayList;
import java.util.List;
public class OOMTest {
public static List<Object> list = new ArrayList<>();
// 启动时设置JVM
// ‐Xms5M ‐Xmx5M ‐XX:+PrintGCDetails ‐XX:+HeapDumpOnOutOfMemoryError ‐XX:HeapDumpPath=D:\jvm.dump
public static void main(String[] args) {
List<Object> list = new ArrayList<>();
int i = 0;
int j = 0;
while (true) {
list.add(new User(i++, j + ""));
new User(j--, j + "");
}
}
}
2).Jstack
用jstack加进程id查找死锁,见如下示例
package com.tuling.jvm;
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("thread1 begin");
Thread.sleep(5000);
} catch (InterruptedException e) {
}
synchronized (lock2) {
System.out.println("thread1 end");
}
}
}).start();
new Thread(() -> {
synchronized (lock2) {
try {
System.out.println("thread2 begin");
Thread.sleep(5000);
} catch (InterruptedException e) {
}
synchronized (lock1) {
System.out.println("thread2 end");
}
}
}).start();
System.out.println("main thread end");
}
}
jstack 13326
“Thread-1” 线程名
prio=5 优先级=5
tid=0x000000001fa9e000 线程id
nid=0x2d64 线程对应的本地线程标识nid
java.lang.Thread.State: BLOCKED 线程状态
3).Jinfo
查看正在运行的Java应用程序的扩展参数 查看jvm的参数
查看java系统参数