Depth understanding jvm-- performance monitoring tool

1.jvm monitoring tools introduced

1.1.jconsole

  JConsole is a JMX-based GUI tool for connecting JVM is running, but this requires the use of JVM manageable mode is activated.

1.2. Start jconsole

  By the "jconsole.exe" start Jconsole under JDK / bin directory, will automatically search out all of the virtual machine process the machine is running, double-click a process and start monitoring.

  Also "remote connection server, remote monitoring of virtual machines.

  

  Added: view the process according to the port number

  netstat -ano | findstr 8080
  explained: | findstr 8080 represents a filtered data include 8080, equivalent to keyword search

1.2.1. Overview page

  After entering the monitoring interface below

  

  Overview page shows an overview of the entire virtual machine is running data.

1.2.2. Memory Monitor

  

1.2.3 Line Monitor

  Here's a thread monitor, you can easily perform deadlock detection is very important

  

1.2.4. Class load monitoring

  

1.2.5.jvm Report

   

1.3.jvisualvm

  And provides functionality similar jconsole, it provided a lot of plug-ins.
  Plug-in, Visual GC (GC visualization) is still relatively easy to use, visual GC can see the specific memory usage.

  Start-up mode, open the java installation directory, start bin / jvisualvm.exe applications.

2. Memory Overflow combat simulation

  This section will be combined with actual cases above jvm monitoring tools, in-depth understanding of the jvm!

2.1 Case I: out of memory combat simulation

  Test code:

 1 package com.wfd360.outofmemory;
 2 
 3 import java.util.ArrayList;
 4 
 5 /**
 6  * VM Args:
 7  * -Xms20m -Xmx20m
 8  */
 9 public class TestMemory {
10     static class OOMObject {
11         public byte[] byt = new byte[1 * 1024 * 1024];
12     }
13 
14     public static void main(String[] args) throws Exception {
15         Thread.sleep(10000);
16         fillHeap(100);
17         Thread.sleep(10000);
18     }
19 
20     public static void fillHeap(int num) throws Exception {
21         ArrayList<OOMObject> list = new ArrayList<OOMObject>();
22         for (int i = 0; i < num; i++) {
23             Thread.sleep(500);
24             list.add(new OOMObject());
25             System.out.println("num=" + i);
26         }
27         System.gc();
28     }
29 
30 
31 }
View Code

  测试jvm参数设置:

  

  测试结果:

  当创建第16个对象时,内存溢出

  

  可视化内存信息观察:

  

  分代回收机制理解:

  https://www.cnblogs.com/newAndHui/p/11106232.html

2.2.案例二:线程等待死循环实战模拟

  测试代码如下:

 1 package com.wfd360.outofmemory;
 2 
 3 import java.io.BufferedReader;
 4 import java.io.InputStreamReader;
 5 
 6 public class TestThread {
 7     /**
 8      * 死循环演示
 9      *
10      */
11     public static void createBusyThread() {
12         Thread thread = new Thread(new Runnable() {
13             @Override
14             public void run() {
15                 System.out.println("createBusyThread");
16                 while (true)
17                     ;
18             }
19         }, "testBusyThread");
20         thread.start();
21     }
22 
23     /**
24      * 线程锁等待
25      *
26      */
27     public static void createLockThread(final Object lock) {
28         Thread thread = new Thread(new Runnable() {
29             @Override
30             public void run() {
31                 System.out.println("createLockThread");
32                 synchronized (lock) {
33                     try {
34                         lock.wait();
35                     } catch (InterruptedException e) {
36                         e.printStackTrace();
37                     }
38                 }
39 
40             }
41         }, "testLockThread");
42         thread.start();
43     }
44     public static void main(String[] args) throws Exception {
45         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
46         br.readLine();
47         createBusyThread();
48         br.readLine();
49         Object object = new Object();
50         createLockThread(object);
51     }
52 }
View Code

 

   线程监视图:

  

  线程dump:

   

  总结:通过线程可视化观察,“testLockThread”线程一直处于等待状态,那么我们就可以使用dump,导出堆栈信息,查看具体原因。

2.3.案例三:线程死锁实战演示

   测试代码:

 1 package com.wfd360.thread;
 2 
 3 public class DeadThread implements Runnable {
 4     //控制锁顺序
 5     private boolean lockFormer;
 6     //对象1
 7     private static Object o1 = new Object();
 8     //对象2
 9     private static Object o2 = new Object();
10 
11     DeadThread(boolean lockFormer) {
12         this.lockFormer = lockFormer;
13     }
14 
15     @Override
16     public void run() {
17         if (this.lockFormer) {
18             synchronized (o1) {
19                 try {
20                     Thread.sleep(500);
21                 } catch (InterruptedException e) {
22                     e.printStackTrace();
23                 }
24                 synchronized (o2) {
25                     System.out.println("1ok");
26                 }
27             }
28         } else {
29             synchronized (o2) {
30                 try {
31                     Thread.sleep(500);
32                 } catch (InterruptedException e) {
33                     e.printStackTrace();
34                 }
35                 synchronized (o1) {
36                     System.out.println("2ok");
37                 }
38             }
39         }
40     }
41 
42     public static void main(String[] args) {
43         for (int i = 0; i < 200; i++) {
44             new Thread(new DeadThread(true)).start();
45             new Thread(new DeadThread(false)).start();
46         }
47     }
48 }
View Code

 

   jvm内存监控观察:

  

  死锁检测:

  

2.3.1.死锁的构成基本条件

1、互斥条件:一份资源每次只能被一个进程或线程使用(在Java中一般体现为,一个对象锁只能被一个线程持有)

2、请求与保持条件:一个进程或线程在等待请求资源被释放时,不释放已占有资源

3、不可剥夺条件:一个进程或线程已经获得的资源不能被其他进程或线程强行剥夺

4、循环等待条件:形成一种循环等待的场景

2.4.案例四:内存快照分析

  测试代码:

 1 package com.wfd360.outofmemory;
 2 
 3 import java.util.ArrayList;
 4 import java.util.List;
 5 
 6 /**
 7  * 演示堆内存溢出
 8  * 配置jvm参数
 9  * VM Args:
10  * -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=f:/test/dump
11  * 参数-XX:+HeapDumpOnOutOfMemoryError可以让虚拟机在出现内存溢出异常时Dump出当前的内存堆转储快照以便事后进行分析,文件在项目中
12  */
13 public class HeapOOM {
14     static class OOMObject {
15         public byte[] byt = new byte[1 * 1024*1024];
16     }
17 
18     public static void main(String[] args) {
19         List<OOMObject> list = new ArrayList<OOMObject>();
20         while (true) {
21             list.add(new OOMObject());
22         }
23     }
24 }
View Code

   jvm参数配置:

  

  测试结果:

  

   这时生产的内存快照在 f:/test/dump 中

  接下来,使用工具分析内存快照:

  1.解压 MemoryAnalyzer-1.5.0.20150527-win32.win32.x86_64.zip

    百度网盘下载链接:https://pan.baidu.com/s/1NYzO2ykruGAURg2SrPJqCQ
    提取码:mtqc
  2.启动 MemoryAnalyzer.exe

    

  3.打开刚才生成的内存快照  f:/test/dump 

    

  4.内存快照分析

    

    从内存快照中可以清楚的看到产生内存溢出的原因。

    

    内存占比列表。

    还有其他的功能,大家自己点击查看。

Guess you like

Origin www.cnblogs.com/newAndHui/p/11105956.html