1、JVM参数类型
(1)标准参数
        例如:-help
                   -server -client
                   -version -showversion
                   -cp -classpath
(2)X参数:非标准化参数
         -Xint:解释执行
         -Xcomp:第一次使用就编译成本地代码
         -Xmixed:混合模式,JVM自己来决定是否编译成本地代码
(3)XX参数:非标准化参数、相对不稳定、主要用于JVM调优和Debug
         ①Boolean类型
                 格式:-XX:[+-]<name> 表示启用 (+) 或者禁用 (-) name属性
                 比如:-XX:+UseConcMarkSweepGC           -XX:+UseG1GC
         ②非Boolean类型
                 格式:-XX:<name>=<value> 表示 name 属性的值是 value
                 比如:-XX:MaxGCPauseMillis=500             -XX:GCTimeRatio=19
         -Xmx 和 -Xms 不是X参数,而是XX参数
         -Xms等价于 -XX:InitialHeapSize;-Xmx 等价于 -XX:MaxHeapSize
2、查看JVM运行时参数
(1)-XX:+PrintFlagsInitial     查看一些初始值
(2)-XX:+PrintFlagsFinal      查看一些最终值

=  表示默认值;  := 表示被用户或者JVM修改后的值
(3)-XX:+UnlockExperimentalVMOptions       解锁实验参数
(4)-XX:+UnlockDiagnosticVMOptions          解锁诊断参数
(5)jps:查看 java 进程      例如:jps -l

(6)jinfo:查看运行时的 JVM 的一些配置参数
         ①查看最大内存:jinfo -flag MapHeapSize 3176(进程ID)
         ②查看垃圾回收器:jinfo -flag useConcMarkSweepGC 3176(进程ID)
                                           jinfo -flag useG1GC 3176(进程ID)
                                           jinfo -flag useParallelGC 3176(进程ID)
3、jstat查看JVM统计信息
         jstat可以查看 类装载、垃圾收集、JIT编译 等信息,jstat -options
            options:-class,-compiler,-gc,-printcompilation,例如
查看jvm进程ID为3804的类装载信息,每格1000ms输出一次,一共输出10次

Loaded:加载类的个数

Bytes:类的大小(KB)

Unloaded:卸载的个数

Time:加载卸载所花的时间

  查看jvm进程ID为3804的垃圾回收信息

S0C、S1C、S0U、S1U:S0和S1的总量与使用量
EC、EU:Eden区总量和使用量
OC、OU:Old区总量和使用量
MC、MU:Metaspace区总量和使用量
CCSC、CCSU:压缩类空间总量和使用量
YGC、YGCT:YoungGC的次数与时间
FGC、FGCT:FullGC的次数和时间
GCT:总的GC时间
     ——JVM内存结构
                       
          S0 与 S1 大小相等,在同一时刻只有一个是启用的,另一个是空的;非堆区是独立于JVM的堆区之外的OS的本地内存,在JDK7之前并没有Metaspace区,而是Perm区,JDK8将Perm区移出了;CCS区是当我们启用的短指针时才有;CodeCache存放的是JIT代码(将java代码转化为native代码)信息,如果没有开启JIT,这部分也是不存在的。
      ——JIT 编译信息查看:-compiler、-printcompilation

Compiled:完成了多少个编译                                    
Failed:失败个数
Invalid:无效个数
Time:编译耗时
FailedType:失败类型
FailedMethod:失败的类名或方法名

4、jmap+MAT实战内存溢出
(1)演示堆内存溢出和非堆内存溢出

@RestController
public class MemoryController {

    private List<User> userList = new ArrayList<>();
    private List<Class<?>> classList = new ArrayList<>();

    /**
    * 演示堆内存溢出
    * VM Args: -Xmx32M -Xms32M
    * @return
    */
    @GetMapping("/heap")
    public String heap(){
        int i = 0;
        while (true){
            userList.add(new User(i++, UUID.randomUUID().toString()));
        }
    }

    /**
    * 演示非堆内存溢出(metaSpace溢出)
    * VM Args: -XX:MetaspaceSize=32M -XX:MaxMetaspaceSize=32M
    * @return
    */
    @GetMapping("/nonheap")
    public String nonheap(){
        while (true){
            classList.addAll(Metaspace.createClasses());
        }
    }
}

public class Metaspace extends ClassLoader{
    public static List<Class<?>> createClasses(){
        // 类持有
        List<Class<?>> classes = new ArrayList<>();
        // 循环1000w次生成1000w个不同的类
        for(int i=0; i<10000000; i++){
            ClassWriter cw = new ClassWriter(0);
            // 定义一个类名称为Class(i),它的访问域名为public,父类为java.lang.Object,不实现任何接口
            cw.visit(Opcodes.V1_1, Opcodes.ACC_PUBLIC, "Class" + i, null, "java/lang/Object", null);
            // 定义构造函数<init>方法
            MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
            // 第一个指令为加载this
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            // 第二个指令为调用父类Object的构造函数
            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
            // 第三条指令为return
            mv.visitInsn(Opcodes.RETURN);
            mv.visitMaxs(1, 1);
            mv.visitEnd();
            Metaspace test = new Metaspace();
            byte[] code = cw.toByteArray();
            // 定义类
            Class<?> exampleClass = test.defineClass("Class" + i, code, 0, code.length);
            classes.add(exampleClass);
        }
        return classes;
    }
}

堆内存溢出异常:
Exception in thread "http-nio-8888-ClientPoller-1" Exception in thread "ContainerBackgroundProcessor[StandardEngine[Tomcat]]" Exception in thread "NioBlockingSelector.BlockPoller-1" Exception in thread "http-nio-8888-exec-2" Exception in thread "http-nio-8888-exec-1" java.lang.OutOfMemoryError: GC overhead limit exceeded
java.lang.OutOfMemoryError: GC overhead limit exceeded
java.lang.OutOfMemoryError: GC overhead limit exceeded

非堆内存溢出异常:
Exception in thread "ContainerBackgroundProcessor[StandardEngine[Tomcat]]" Exception in thread "http-nio-8888-exec-1" java.lang.OutOfMemoryError: Metaspace
java.lang.OutOfMemoryError: Metaspace

(2)那么如何来来解决以上的两个问题呢?
        可以分析内存映像文件,那么如何导出内存映像文件?
① 内存溢出时自动导出,可以设置参数如下:
          -XX:+HeapDumpOnOutOfMemoryError
          -XX:HeapDumpPath=./
      设置JVM运行参数”-Xmx32M -Xms32M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./“,程序运行后堆内存溢出时:
java.lang.OutOfMemoryError: GC overhead limit exceeded
Dumping heap to ./\java_pid22044.hprof ...
Heap dump file created [42932268 bytes in 0.374 secs]
Exception in thread "http-nio-8888-AsyncTimeout" Exception in thread "http-nio-8888-exec-2" java.lang.OutOfMemoryError: GC overhead limit exceeded
java.lang.OutOfMemoryError: GC overhead limit exceeded
Exception in thread "ContainerBackgroundProcessor[StandardEngine[Tomcat]]" java.lang.OutOfMemoryError: GC overhead limit exceeded

② 使用 jmap 命令手动导出
       jmap 常用参数选项:-heap、-clstats、-dump:<dump-options>、-F
                          
(3)如何查看内存映像文件呢?
可以使用 MAT (Memory Analysis Tool)打开文件进行分析,如下图


它怀疑 a 和 b 可能导致内存溢出,这个很显然嘛
② 接下来可以看下堆内存中的对象数量:

查看每个强引用对象:


③接下来可以查看对象所占用的栈字节数大小

4、jstack实战死循环与死锁
        jstack 命令可以查看jvm中所有的线程信息,jstack <options> pid,如下:

2018-12-03 15:29:40
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.131-b11 mixed mode):

"DestroyJavaVM" #37 prio=5 os_prio=0 tid=0x000000005856a800 nid=0x50cc waiting on condition [0x0000000000000000]
  java.lang.Thread.State: RUNNABLE

"http-nio-8888-AsyncTimeout" #35 daemon prio=5 os_prio=0 tid=0x000000005856a000 nid=0x4a88 waiting on condition [0x000000005bb9f000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at org.apache.coyote.AbstractProtocol$AsyncTimeout.run(AbstractProtocol.java:1149)
        at java.lang.Thread.run(Thread.java:748)
/*
"http-nio-8888-AsyncTimeout":线程名字;      #35:内部类的标号;      daemon:表明是一个后台线程;      prio:线程的优先级;      os_prio:对应的操作系统的优先级
nid=0x4a88:对应操作系统的PID(十进制),是一个十六进制的数
 java.lang.Thread.State: TIMED_WAITING (sleeping):线程的状态
下面就是一些堆栈信息
at java.lang.Thread.sleep(Native Method)
        at org.apache.coyote.AbstractProtocol$AsyncTimeout.run(AbstractProtocol.java:1149)
        at java.lang.Thread.run(Thread.java:748)
*/

"http-nio-8888-Acceptor-0" #34 daemon prio=5 os_prio=0 tid=0x0000000058569000 nid=0x5118 runnable [0x000000005b0de000]
  java.lang.Thread.State: RUNNABLE
        at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method)
        at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:422)
        at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:250)
        - locked <0x00000000ffc123a0> (a java.lang.Object)
        at org.apache.tomcat.util.net.NioEndpoint$Acceptor.run(NioEndpoint.java:482)
        at java.lang.Thread.run(Thread.java:748)

"http-nio-8888-ClientPoller-1" #33 daemon prio=5 os_prio=0 tid=0x0000000058568800 nid=0x56e8 runnable [0x000000005ae9e000]
  java.lang.Thread.State: RUNNABLE
        at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(Native Method)
        at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll(WindowsSelectorImpl.java:296)
        at sun.nio.ch.WindowsSelectorImpl$SubSelector.access$400(WindowsSelectorImpl.java:278)
        at sun.nio.ch.WindowsSelectorImpl.doSelect(WindowsSelectorImpl.java:159)
        at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
        - locked <0x00000000ff5c8d18> (a sun.nio.ch.Util$3)
        - locked <0x00000000ff5c8d08> (a java.util.Collections$UnmodifiableSet)
        - locked <0x00000000ff5c8bb8> (a sun.nio.ch.WindowsSelectorImpl)
        at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
        at org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:825)
        at java.lang.Thread.run(Thread.java:748)

"http-nio-8888-ClientPoller-0" #32 daemon prio=5 os_prio=0 tid=0x0000000058567800 nid=0x4880 runnable [0x000000005620e000]
  java.lang.Thread.State: RUNNABLE
        at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(Native Method)
        at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll(WindowsSelectorImpl.java:296)
        at sun.nio.ch.WindowsSelectorImpl$SubSelector.access$400(WindowsSelectorImpl.java:278)
        at sun.nio.ch.WindowsSelectorImpl.doSelect(WindowsSelectorImpl.java:159)
        at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
        - locked <0x00000000ff5c4ac8> (a sun.nio.ch.Util$3)
        - locked <0x00000000ff5c4ab8> (a java.util.Collections$UnmodifiableSet)
        - locked <0x00000000ff5c4968> (a sun.nio.ch.WindowsSelectorImpl)
        at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
        at org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:825)
        at java.lang.Thread.run(Thread.java:748)
/*
exec:工作线程,这里一共有10个
*/

"http-nio-8888-exec-10" #31 daemon prio=5 os_prio=0 tid=0x0000000058567000 nid=0x46ac waiting on condition [0x000000005acfe000]
  java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000ffc98788> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

"http-nio-8888-exec-9" #30 daemon prio=5 os_prio=0 tid=0x0000000058566000 nid=0x4854 waiting on condition [0x000000005a68f000]
  java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000ffc98788> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

"http-nio-8888-exec-8" #29 daemon prio=5 os_prio=0 tid=0x0000000058565800 nid=0x5714 waiting on condition [0x000000005abce000]
  java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000ffc98788> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

"http-nio-8888-exec-7" #28 daemon prio=5 os_prio=0 tid=0x0000000058564800 nid=0x51ec waiting on condition [0x0000000057a7e000]
  java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000ffc98788> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

"http-nio-8888-exec-6" #27 daemon prio=5 os_prio=0 tid=0x0000000058564000 nid=0x52d4 waiting on condition [0x000000005a92e000]
  java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000ffc98788> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

"http-nio-8888-exec-5" #26 daemon prio=5 os_prio=0 tid=0x0000000058563000 nid=0x5064 waiting on condition [0x000000005a14f000]
  java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000ffc98788> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

"http-nio-8888-exec-4" #25 daemon prio=5 os_prio=0 tid=0x0000000058562800 nid=0x4f8c waiting on condition [0x000000005a7bf000]
  java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000ffc98788> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

"http-nio-8888-exec-3" #24 daemon prio=5 os_prio=0 tid=0x000000005839b000 nid=0x4464 waiting on condition [0x000000005a58e000]
  java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000ffc98788> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

"http-nio-8888-exec-2" #23 daemon prio=5 os_prio=0 tid=0x000000005839a800 nid=0x3cec waiting on condition [0x000000005a41e000]
  java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000ffc98788> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

"http-nio-8888-exec-1" #22 daemon prio=5 os_prio=0 tid=0x0000000058399800 nid=0x52a4 waiting on condition [0x000000005a24e000]
  java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000ffc98788> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

"NioBlockingSelector.BlockPoller-1" #21 daemon prio=5 os_prio=0 tid=0x000000005845c800 nid=0x5334 runnable [0x00000000591ff000]
  java.lang.Thread.State: RUNNABLE
        at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(Native Method)
        at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll(WindowsSelectorImpl.java:296)
        at sun.nio.ch.WindowsSelectorImpl$SubSelector.access$400(WindowsSelectorImpl.java:278)
        at sun.nio.ch.WindowsSelectorImpl.doSelect(WindowsSelectorImpl.java:159)
        at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
        - locked <0x00000000ffc12df0> (a sun.nio.ch.Util$3)
        - locked <0x00000000ffc12de0> (a java.util.Collections$UnmodifiableSet)
        - locked <0x00000000ffc12c80> (a sun.nio.ch.WindowsSelectorImpl)
        at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
        at org.apache.tomcat.util.net.NioBlockingSelector$BlockPoller.run(NioBlockingSelector.java:298)

"container-0" #20 prio=5 os_prio=0 tid=0x0000000058ac5000 nid=0x45b4 waiting on condition [0x0000000059e2f000]
  java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at org.apache.catalina.core.StandardServer.await(StandardServer.java:427)
        at org.springframework.boot.web.embedded.tomcat.TomcatWebServer$1.run(TomcatWebServer.java:182)

"ContainerBackgroundProcessor[StandardEngine[Tomcat]]" #19 daemon prio=5 os_prio=0 tid=0x0000000058a9a000 nid=0x57e4 waiting on condition [0x0000000059c7f000]
  java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1356)
        at java.lang.Thread.run(Thread.java:748)

"Service Thread" #13 daemon prio=9 os_prio=0 tid=0x00000000546a5000 nid=0x5430 runnable [0x0000000000000000]
  java.lang.Thread.State: RUNNABLE
/*
C1、C2是后台JIT编译的线程
*/

"C1 CompilerThread3" #12 daemon prio=9 os_prio=2 tid=0x0000000054615800 nid=0x538c waiting on condition [0x0000000000000000]
  java.lang.Thread.State: RUNNABLE

"C2 CompilerThread2" #11 daemon prio=9 os_prio=2 tid=0x0000000054614800 nid=0x1b04 waiting on condition [0x0000000000000000]
  java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" #10 daemon prio=9 os_prio=2 tid=0x0000000054614000 nid=0x50d8 waiting on condition [0x0000000000000000]
  java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #9 daemon prio=9 os_prio=2 tid=0x0000000054618000 nid=0x550c waiting on condition [0x0000000000000000]
  java.lang.Thread.State: RUNNABLE
/*
JDWP:调试线程
*/

"JDWP Command Reader" #8 daemon prio=10 os_prio=0 tid=0x0000000054601800 nid=0x5010 runnable [0x0000000000000000]
  java.lang.Thread.State: RUNNABLE

"JDWP Event Helper Thread" #7 daemon prio=10 os_prio=0 tid=0x00000000545fe800 nid=0x5488 runnable [0x0000000000000000]
  java.lang.Thread.State: RUNNABLE

"JDWP Transport Listener: dt_socket" #6 daemon prio=10 os_prio=0 tid=0x00000000545f1800 nid=0x52d8 runnable [0x0000000000000000]
  java.lang.Thread.State: RUNNABLE

"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x00000000545d4000 nid=0x4658 waiting on condition [0x0000000000000000]
  java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x00000000545eb000 nid=0x4d94 runnable [0x0000000000000000]
  java.lang.Thread.State: RUNNABLE

"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x0000000053403000 nid=0x3fbc in Object.wait() [0x0000000055a5f000]
  java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000000fe3c8328> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
        - locked <0x00000000fe3c8328> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)

"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x00000000533fc000 nid=0x54e4 in Object.wait() [0x000000005589f000]
  java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000000fe204a98> (a java.lang.ref.Reference$Lock)
        at java.lang.Object.wait(Object.java:502)
        at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
        - locked <0x00000000fe204a98> (a java.lang.ref.Reference$Lock)
        at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)

"VM Thread" os_prio=2 tid=0x0000000054572800 nid=0x5248 runnable
/*
GC:垃圾回收线程
*/

"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00000000026ef800 nid=0x3dac runnable

"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00000000026f1800 nid=0x4a40 runnable

"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00000000026f3000 nid=0x536c runnable

"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00000000026f4800 nid=0x5684 runnable

"GC task thread#4 (ParallelGC)" os_prio=0 tid=0x00000000026f7800 nid=0x54e0 runnable

"GC task thread#5 (ParallelGC)" os_prio=0 tid=0x00000000026f9000 nid=0x4584 runnable

"GC task thread#6 (ParallelGC)" os_prio=0 tid=0x00000000026fc000 nid=0x54f4 runnable

"GC task thread#7 (ParallelGC)" os_prio=0 tid=0x00000000026fd000 nid=0x2dd4 runnable

"VM Periodic Task Thread" os_prio=2 tid=0x00000000546c3800 nid=0x24c waiting on condition

JNI global references: 16806

Java线程状态:

NEW    新建    WAITING    等待
RUNNABLE    运行    TIMED_WAITING    限时等待
BLOCKED    阻塞    TERMINATED    终止

接下来演示死循环和死锁

@RestController
public class CpuController {

    /**
     * 演示CPU飙高
     * @return
     */
    @RequestMapping("/loop")

    public List<Long> loop(){
        String data = "{\"data\":[{\"partnerid\":]";
        return getPartneridsFromjson(data);
    }

    private Object lock1 = new Object();
    private Object lock2 = new Object();
    /**
     * 演示死锁
     * @return
     */
    @RequestMapping("/deadlock")

    public String deadlock(){
        new Thread(() -> {
            synchronized (lock1){
                try{
                    Thread.sleep(1000);
                }catch (Exception e){}
                synchronized (lock2){
                    System.out.println("Thread1 over");
                }
            }
        }).start();
        new Thread(() -> {
            synchronized (lock2){
                try{
                    Thread.sleep(1000);
                }catch (Exception e){}
                synchronized (lock1){
                    System.out.println("Thread2 over");
                }
            }
        }).start();
        return "deadlock";
    }

    public static List<Long> getPartneridsFromjson(String data) {
        //{\"data\":[{\"partnerid\":982,\"count\":\"10000\",\"cityid\":\"11\"},{\"partnerid\":983,\"count\":\"10000\",\"cityid\":\"11\"},{\"partnerid\":984,\"count\":\"10000\",\"cityid\":\"11\"}]}
        //上面是正常的数据
        List<Long> list = new ArrayList<>(2);
        if(data == null || data.length() <=0){
            return list;
        }
        int datapos = data.indexOf("data");
        if(datapos < 0){
            return list;
        }
        int leftBracket = data.indexOf("[", datapos);
        int rightBracket = data.indexOf("]", datapos);
        if(leftBracket < 0 || rightBracket < 0) {
            return list;
        }
        String partners = data.substring(leftBracket+1, rightBracket);
        if (partners == null || partners.length() <=0){
            return list;
        }
        while (partners!=null && partners.length()>0){
            int idpos = partners.indexOf("partnerid");
            if(idpos < 0){
                break;
            }
            int colonpos = partners.indexOf(":", idpos);
            int commapos = partners.indexOf(",", idpos);
            if(colonpos<0 || commapos<0){
                //partners = partners.substring(idpos+"partnerid".length());//1
                continue;
            }
            String pid = partners.substring(colonpos + 1, commapos);
            if(pid ==null || pid.length() <=0){
                //partners = partners.substring(idpos+"partnerid".length());//2
                continue;
            }
            try {
                list.add(Long.parseLong(pid));
            } catch (Exception e) {
                e.printStackTrace();
            }
            partners = partners.substring(commapos);
        }
        return list;
    }
}

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐