深入理解jvm–性能监控工具

释放双眼,带上耳机,听听看~!

1.jvm监控工具介绍

1.1.jconsole

JConsole是一个基于JMX的GUI工具,用于连接正在运行的JVM,不过此JVM需要使用可管理的模式启动。

1.2.启动jconsole

通过JDK/bin目录下的“jconsole.exe”启动Jconsole后,将自动搜索出本机运行的所有虚拟机进程,双击其中一个进程即可开始监控。

也可以“远程连接服务器,进行远程虚拟机的监控。

深入理解jvm--性能监控工具

补充:根据端口号查看进程

netstat -ano |findstr 8080
解释:|findstr 8080 表示过滤出包括8080的数据,相当于关键字查找

1.2.1.概览页面

进入监控界面后如下图

深入理解jvm--性能监控工具

概述页面显示的是整个虚拟机主要运行数据的概览。

1.2.2.内存监控

深入理解jvm--性能监控工具

1.2.3线程监控

此处的线程监控,可以方便的进行死锁检测,非常重要

深入理解jvm--性能监控工具

1.2.4.类加载监控

深入理解jvm--性能监控工具

1.2.5.jvm报表

   深入理解jvm--性能监控工具

1.3.jvisualvm

提供了和jconsole的功能类似,提供了一大堆的插件。
插件中,Visual GC(可视化GC)还是比较好用的,可视化GC可以看到内存的具体使用情况。

启动方式,打开java安装目录,启动 bin/jvisualvm.exe 应用。

2.内存溢出实战模拟

本节将以实际案例结合上面的jvm监控工具,深入的理解jvm!

2.1.案例一:内存溢出实战模拟

测试代码:

深入理解jvm--性能监控工具深入理解jvm--性能监控工具


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
11 package com.wfd360.outofmemory;
2 2
3 3 import java.util.ArrayList;
4 4
5 5 /**
6 6  * VM Args:
7 7  * -Xms20m -Xmx20m
8 8  */
9 9 public class TestMemory {
1010     static class OOMObject {
1111         public byte[] byt = new byte[1 * 1024 * 1024];
1212     }
1313
1414     public static void main(String[] args) throws Exception {
1515         Thread.sleep(10000);
1616         fillHeap(100);
1717         Thread.sleep(10000);
1818     }
1919
2020     public static void fillHeap(int num) throws Exception {
2121         ArrayList<OOMObject> list = new ArrayList<OOMObject>();
2222         for (int i = 0; i < num; i++) {
2323             Thread.sleep(500);
2424             list.add(new OOMObject());
2525             System.out.println("num=" + i);
2626         }
2727         System.gc();
2828     }
2929
3030
3131 }
32

View Code

测试jvm参数设置:

深入理解jvm--性能监控工具

测试结果:

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

深入理解jvm--性能监控工具

可视化内存信息观察:

深入理解jvm--性能监控工具

分代回收机制理解:

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

2.2.案例二:线程的异常等待与异常运行

测试代码如下:

深入理解jvm--性能监控工具深入理解jvm--性能监控工具


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
11 package com.wfd360.outofmemory;
2 2
3 3 import java.io.BufferedReader;
4 4 import java.io.InputStreamReader;
5 5
6 6 public class TestThread {
7 7     /**
8 8      * 死循环演示
9 9      *
1010      */
1111     public static void createBusyThread() {
1212         Thread thread = new Thread(new Runnable() {
1313             @Override
1414             public void run() {
1515                 System.out.println("createBusyThread");
1616                 while (true)
1717                     ;
1818             }
1919         }, "testBusyThread");
2020         thread.start();
2121     }
2222
2323     /**
2424      * 线程锁等待
2525      *
2626      */
2727     public static void createLockThread(final Object lock) {
2828         Thread thread = new Thread(new Runnable() {
2929             @Override
3030             public void run() {
3131                 System.out.println("createLockThread");
3232                 synchronized (lock) {
3333                     try {
3434                         lock.wait();
3535                     } catch (InterruptedException e) {
3636                         e.printStackTrace();
3737                     }
3838                 }
3939
4040             }
4141         }, "testLockThread");
4242         thread.start();
4343     }
4444     public static void main(String[] args) throws Exception {
4545         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
4646         br.readLine();
4747         createBusyThread();
4848         br.readLine();
4949         Object object = new Object();
5050         createLockThread(object);
5151     }
5252 }
53

View Code

 

   线程监视图:

深入理解jvm--性能监控工具

线程dump:

   深入理解jvm--性能监控工具

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

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

   测试代码:

深入理解jvm--性能监控工具深入理解jvm--性能监控工具


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
11 package com.wfd360.thread;
2 2
3 3 public class DeadThread implements Runnable {
4 4     //控制锁顺序
5 5     private boolean lockFormer;
6 6     //对象1
7 7     private static Object o1 = new Object();
8 8     //对象2
9 9     private static Object o2 = new Object();
1010
1111     DeadThread(boolean lockFormer) {
1212         this.lockFormer = lockFormer;
1313     }
1414
1515     @Override
1616     public void run() {
1717         if (this.lockFormer) {
1818             synchronized (o1) {
1919                 try {
2020                     Thread.sleep(500);
2121                 } catch (InterruptedException e) {
2222                     e.printStackTrace();
2323                 }
2424                 synchronized (o2) {
2525                     System.out.println("1ok");
2626                 }
2727             }
2828         } else {
2929             synchronized (o2) {
3030                 try {
3131                     Thread.sleep(500);
3232                 } catch (InterruptedException e) {
3333                     e.printStackTrace();
3434                 }
3535                 synchronized (o1) {
3636                     System.out.println("2ok");
3737                 }
3838             }
3939         }
4040     }
4141
4242     public static void main(String[] args) {
4343         for (int i = 0; i < 200; i++) {
4444             new Thread(new DeadThread(true)).start();
4545             new Thread(new DeadThread(false)).start();
4646         }
4747     }
4848 }
49

View Code

 

   jvm内存监控观察:

深入理解jvm--性能监控工具

死锁检测:

深入理解jvm--性能监控工具

2.3.1.死锁的构成基本条件

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

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

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

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

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

测试代码:

深入理解jvm--性能监控工具深入理解jvm--性能监控工具


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

View Code

   jvm参数配置:

深入理解jvm--性能监控工具

测试结果:

深入理解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

深入理解jvm--性能监控工具

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

深入理解jvm--性能监控工具

4.内存快照分析

深入理解jvm--性能监控工具

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

深入理解jvm--性能监控工具

内存占比列表。

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

转载于:https://www.cnblogs.com/newAndHui/p/11105956.html

给TA打赏
共{{data.count}}人
人已打赏
安全技术

用node.js从零开始去写一个简单的爬虫

2021-12-21 16:36:11

安全技术

从零搭建自己的SpringBoot后台框架(二十三)

2022-1-12 12:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索