前置启动程序
    事先启动一个web应用程序,用jps查看其进程id,接着用各种jdk自带命令优化应用
    image.png

    1).Jmap 查看内存信息
    此命令可以用来查看内存信息,实例个数以及占用内存大小
    jmap -histo 130794 > jmap.txt
    打开jmap.txt,文件内容如下:
    image.png
    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
    image.png
    堆内存dump
    windows下:
    jmap ‐dump:format=b,file=common.hprof 130794
    linux下:
    jmap -dump:format=b,file=common.dat 130794
    image.png
    用jvisualvm命令工具导入该dump文件分析
    cmd中输入jvisualvm来打开工具
    点击左上角的文件->装入->堆文件->选择刚才导出的common.dat文件,如下图
    image.png也可以设置内存溢出自动导出dump文件(内存很大的时候,可能会导不出来)
    如下面的这个代码,在运行的时候,如果OOM了,可以在D盘下找到当时OOM的dump快照文件信息进行导入分析,文件后缀设置dump、dat、hprof都可以:
    1. -XX:+HeapDumpOnOutOfMemoryError
    2. -XX:HeapDumpPath=./ (路径)

    1. package com.tuling.jvm;
    2. import java.util.ArrayList;
    3. import java.util.List;
    4. public class OOMTest {
    5. public static List<Object> list = new ArrayList<>();
    6. // 启动时设置JVM
    7. // ‐Xms5M ‐Xmx5M ‐XX:+PrintGCDetails ‐XX:+HeapDumpOnOutOfMemoryError ‐XX:HeapDumpPath=D:\jvm.dump
    8. public static void main(String[] args) {
    9. List<Object> list = new ArrayList<>();
    10. int i = 0;
    11. int j = 0;
    12. while (true) {
    13. list.add(new User(i++, j + ""));
    14. new User(j--, j + "");
    15. }
    16. }
    17. }

    2).Jstack
    用jstack加进程id查找死锁,见如下示例

    1. package com.tuling.jvm;
    2. public class DeadLockTest {
    3. private static Object lock1 = new Object();
    4. private static Object lock2 = new Object();
    5. public static void main(String[] args) {
    6. new Thread(() -> {
    7. synchronized (lock1) {
    8. try {
    9. System.out.println("thread1 begin");
    10. Thread.sleep(5000);
    11. } catch (InterruptedException e) {
    12. }
    13. synchronized (lock2) {
    14. System.out.println("thread1 end");
    15. }
    16. }
    17. }).start();
    18. new Thread(() -> {
    19. synchronized (lock2) {
    20. try {
    21. System.out.println("thread2 begin");
    22. Thread.sleep(5000);
    23. } catch (InterruptedException e) {
    24. }
    25. synchronized (lock1) {
    26. System.out.println("thread2 end");
    27. }
    28. }
    29. }).start();
    30. System.out.println("main thread end");
    31. }
    32. }

    jstack 13326
    image.png
    “Thread-1” 线程名
    prio=5 优先级=5
    tid=0x000000001fa9e000 线程id
    nid=0x2d64 线程对应的本地线程标识nid
    java.lang.Thread.State: BLOCKED 线程状态
    image.png
    3).Jinfo
    查看正在运行的Java应用程序的扩展参数 查看jvm的参数
    image.png
    查看java系统参数
    image.png