JVM之jvisualvm多合一故障处理工具

news2024/11/15 9:10:49

jvisualvm多合一故障处理工具

1、visualvm介绍

VisualVM是一款免费的,集成了多个 JDK 命令行工具的可视化工具,它能为您提供强大的分析能力,对 Java 应

用程序做性能分析和调优。这些功能包括生成和分析海量数据、跟踪内存泄漏、监控垃圾回收器、执行内存和

CPU 分析,同时它还支持在 MBeans 上进行浏览和操作。

本文主要介绍如何使用 VisualVM 进行性能分析及调优。

VisualVM位于{JAVA_HOME}/bin目录中。

在linux和windows下通过jvisualvm启动。

在这里插入图片描述

在这里插入图片描述

下面我们来看visualvm的各种功能。

2、查看jvm配置信息

第一步:点击左边窗口显示正在运行的java进程

在这里插入图片描述

在这里插入图片描述

第二步:点击右侧窗口概述,可以查看各种配置信息

在这里插入图片描述

通过jdk提供的jinfo命令工具也可以查看上面的信息。

在这里插入图片描述

在这里插入图片描述

3、查看cpu、内存、类、线程监控信息

在这里插入图片描述

4、查看堆的变化

步骤一:运行下面的代码

每隔3秒,堆内存使用新增100M。

package com.example.controller;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

public class Demo4 {
    public static final int _1M = 1024 * 1024;

    public static void main(String[] args) throws InterruptedException {
        List<Object> list = new ArrayList<>();
        for (int i = 0; i < 1000; i++) {
            list.add(new byte[100 * _1M]);
            TimeUnit.SECONDS.sleep(3);
            System.out.println(i);
        }
    }
}

步骤二:在VisualVM可以很清晰的看到堆内存变化信息。

在这里插入图片描述

4、查看堆快照

步骤一:点击监视->堆(dump)可以生产堆快照信息.

在这里插入图片描述

生成了以heapdump开头的一个选项卡,内容如下:

在这里插入图片描述

对于堆 dump来说,在远程监控jvm的时候,VisualVM是没有这个功能的,只有本地监控的时候才有。

5、导出堆快照文件

步骤一:查看堆快照,此步骤可以参考上面的查看堆快照功能

步骤二:右键点击另存为,即可导出hprof堆快照文件,可以发给其他同事分析使用

在这里插入图片描述

6、查看class对象加载信息

这次来看下永久保留区域PermGen使用情况。

步骤一:运行一段类加载的程序。

package com.example.controller;

import java.io.File;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

public class Demo5 {

    private static List<Object> insList = new ArrayList<Object>();

    public static void main(String[] args) throws Exception {
        permLeak();
    }

    private static void permLeak() throws Exception {
        for (int i = 0; i < 2000; i++) {
            URL[] urls = getURLS();
            URLClassLoader urlClassloader = new URLClassLoader(urls, null);
            Class<?> logfClass = Class.forName("org.apache.commons.logging.LogFactory", true, urlClassloader);
            Method getLog = logfClass.getMethod("getLog", String.class);
            Object result = getLog.invoke(logfClass, "TestPermGen");
            insList.add(result);
            System.out.println(i + ": " + result);
            if (i % 100 == 0) {
                TimeUnit.SECONDS.sleep(1);
            }
        }
    }

    private static URL[] getURLS() throws MalformedURLException {
        File libDir = new File("C:\\zsxsoftware\\apache-maven-3.3.9-bin\\repository\\commons-logging\\commons-logging\\1.1.1");
        File[] subFiles = libDir.listFiles();
        int count = subFiles.length;
        URL[] urls = new URL[count];
        for (int i = 0; i < count; i++) {
            urls[i] = subFiles[i].toURI().toURL();
        }
        return urls;
    }
}

步骤二:打开visualvm查看,metaspace。

在这里插入图片描述

7、CPU分析:发现cpu使用率最高的方法

CPU 性能分析的主要目的是统计函数的调用情况及执行时间,或者更简单的情况就是统计应用程序的 CPU 使用情

况。没有程序运行时的 CPU 使用情况如下图:

在这里插入图片描述

下面我们写一个cpu占用率比较高的程序。

步骤一:运行下列程序。

package com.example.controller;

public class Demo6 {

    public static void main(String[] args) throws InterruptedException {
        cpuFix();
    }
    /**
     * cpu 运行固定百分比
     *
     * @throws InterruptedException
     */
    public static void cpuFix() throws InterruptedException {
        // 80%的占有率
        int busyTime = 8;
        // 20%的占有率
        int idelTime = 2;
        // 开始时间
        long startTime = 0;
        while (true) {
            // 开始时间
            startTime = System.currentTimeMillis();
            /*
             * 运行时间
             */
            while (System.currentTimeMillis() - startTime < busyTime) {
                ;
            }
            // 休息时间
            Thread.sleep(idelTime);
        }
    }
}

步骤二:打开visualvm查看cpu使用情况,我的电脑是8核的,如下图:

在这里插入图片描述

过高的 CPU 使用率可能是我们的程序代码性能有问题导致的。可以切换到抽样器对cpu进行采样,可以擦看到那

个方法占用的cpu最高,然后进行优化。

在这里插入图片描述

从图中可以看出cpuFix方法使用cpu最多,然后就可以进行响应的优化了。

8、查看线程快照:发现死锁问题

Java 语言能够很好的实现多线程应用程序。当我们对一个多线程应用程序进行调试或者开发后期做性能调优的时

候,往往需要了解当前程序中所有线程的运行状态,是否有死锁、热锁等情况的发生,从而分析系统可能存在的问

题。

在 VisualVM 的监视标签内,我们可以查看当前应用程序中所有活动线程(Live threads)和守护线程(Daemon

threads)的数量等实时信息。

可以查看线程快照,发现系统的死锁问题。

下面我们将通过visualvm来排查一个死锁问题。

步骤一:运行下面的代码:

package com.example.controller;

public class Demo7 {

    public static void main(String[] args) {
        Obj1 obj1 = new Obj1();
        Obj2 obj2 = new Obj2();
        Thread thread1 = new Thread(new SynAddRunalbe(obj1, obj2, 1, 2, true));
        thread1.setName("thread1");
        thread1.start();
        Thread thread2 = new Thread(new SynAddRunalbe(obj1, obj2, 2, 1, false));
        thread2.setName("thread2");
        thread2.start();
    }

    /**
     * 线程死锁等待演示
     */
    public static class SynAddRunalbe implements Runnable {
        Obj1 obj1;
        Obj2 obj2;
        int a, b;
        boolean flag;

        public SynAddRunalbe(Obj1 obj1, Obj2 obj2, int a, int b, boolean flag) {
            this.obj1 = obj1;
            this.obj2 = obj2;
            this.a = a;
            this.b = b;
            this.flag = flag;
        }

        @Override
        public void run() {
            try {
                if (flag) {
                    synchronized (obj1) {
                        Thread.sleep(100);
                        synchronized (obj2) {
                            System.out.println(a + b);
                        }
                    }
                } else {
                    synchronized (obj2) {
                        Thread.sleep(100);
                        synchronized (obj1) {
                            System.out.println(a + b);
                        }
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static class Obj1 {
    }

    public static class Obj2 {
    }
}

程序中:thread1持有obj1的锁,thread2持有obj2的锁,thread1等待获取obj2的锁,thread2等待获取obj1的

锁,相互需要获取的锁都被对方持有者,造成了死锁。程序中出现了死锁的情况,我们是比较难以发现的。需要依

靠工具解决。

步骤二:打开visualvm查看堆栈信息:

在这里插入图片描述

点击dump,生成线程堆栈信息:

在这里插入图片描述

在这里插入图片描述

可以看到Found one Java-level deadlock,包含了导致死锁的代码。

Found one Java-level deadlock:
=============================
"thread2":
  waiting to lock monitor 0x000000001d201fd8 (object 0x000000076b5ff7c8, a com.example.controller.Demo7$Obj1),
  which is held by "thread1"
"thread1":
  waiting to lock monitor 0x000000001d203478 (object 0x000000076b601e50, a com.example.controller.Demo7$Obj2),
  which is held by "thread2"

Java stack information for the threads listed above:
===================================================
"thread2":
	at com.example.controller.Demo7$SynAddRunalbe.run(Demo7.java:47)
	- waiting to lock <0x000000076b5ff7c8> (a com.example.controller.Demo7$Obj1)
	- locked <0x000000076b601e50> (a com.example.controller.Demo7$Obj2)
	at java.lang.Thread.run(Thread.java:745)
"thread1":
	at com.example.controller.Demo7$SynAddRunalbe.run(Demo7.java:40)
	- waiting to lock <0x000000076b601e50> (a com.example.controller.Demo7$Obj2)
	- locked <0x000000076b5ff7c8> (a com.example.controller.Demo7$Obj1)
	at java.lang.Thread.run(Thread.java:745)

Found 1 deadlock.

上面这段信息可以看出,thread1持有Obj1对象的锁,等待获取Obj2的锁,thread2持有Obj2的锁,等待获取

Obj1的锁,导致了死锁。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1248111.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

应用内测分发平台如何上传应用包体?

●您可免费将您的应用&#xff08;支持苹果.ios安卓.apk文件&#xff09;上传至咕噜分发平台&#xff0c;我们将免费为应用生成下载信息&#xff0c;但咕噜分发将会对应用的下载次数进行收费&#xff08;每个账号都享有免费赠送的下载点数以及参加活动的赠送点数&#xff09;&a…

RTMDet原理与代码解析

paper&#xff1a;RTMDet: An Empirical Study of Designing Real-Time Object Detectors official implementation&#xff1a;https://github.com/open-mmlab/mmdetection/tree/main/configs/rtmdet 本文的创新点 Backbone and Neck 在backbone的basic building block中采…

Spark SQL 时间格式处理

初始化Spark Sql package pbcp_2023.clear_dataimport org.apache.spark.SparkConf import org.apache.spark.sql.SparkSession import org.apache.spark.sql.functions.{current_date, current_timestamp}object twe_2 {def main(args: Array[String]): Unit {val con new …

js获取时间日期

目录 Date 对象 1. 获取当前时间 2. 获取特定日期时间 Date 对象的方法 1. 获取各种日期时间组件 2. 获取星期几 3. 获取时间戳 格式化日期时间 1. 使用 toLocaleString() 方法 2. 使用第三方库 UNIX 时间戳 内部表示 时区 Date 对象 JavaScript中内置的 Date 对象…

获取DOM元素和类型判断

一、获取dom元素 <div id"one" class"one">我是第一个div</div> <div>我是第二个div</div> <div name"username">我是第三个div</div> <input type"text" name"username"> 1.qu…

【完美世界】叶倾仙强势登场,孔雀神主VS护道人,石昊重逢清漪

Hello,小伙伴们&#xff0c;我是拾荒君。 《完美世界》国漫第138集已更新。在这一集中&#xff0c;天人族的行为让人大跌眼镜&#xff0c;他们不仅没有对石昊感恩戴德&#xff0c;反而一心想要夺取他身上的所有秘法宝术。天人族的护道人登场&#xff0c;试图以强大的实力压制石…

Theta*: Any-Angle Path Planning on Grids 原文翻译

Theta*: Any-Angle Path Planning on Grids 文章目录 Theta*: Any-Angle Path Planning on Grids翻译摘要1.Introduction2. Path-Planning Problem and Notation3. Existing Terrain Discretizations4.Existing Path-Planning Algorithms4.1 A* on GridsA* with Post-Smoothed …

2023年【R1快开门式压力容器操作】考试资料及R1快开门式压力容器操作复审考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 R1快开门式压力容器操作考试资料参考答案及R1快开门式压力容器操作考试试题解析是安全生产模拟考试一点通题库老师及R1快开门式压力容器操作操作证已考过的学员汇总&#xff0c;相对有效帮助R1快开门式压力容器操作复…

python获取json所有节点和子节点

使用python获取json的所有父结点和子节点 并使用父节点加下划线命名子节点 先展示一段json代码 {"level1": {"level2": {"level3": [{"level4": "4value"},{"level4_2": "4_2value"}]},"level2_…

毅速丨3D打印随形水路为何受到模具制造追捧

在模具制造行业中&#xff0c;随形水路镶件正逐渐成为一种革命性的技术&#xff0c;其提高冷却效率、优化产品设计、降低成本等优点&#xff0c;为模具制造带来了巨大的创新价值。 随形水路是一种根据产品形状定制的冷却水路&#xff0c;其镶件可以均匀地分布在模具的表面或内部…

迪科DTC-F81收费机DTC-F82

迪科DTC-F81收费机是一款挂式收费机&#xff0c;广泛应用的学校食堂刷卡消费&#xff0c;DTC-F82收费机是台式消费机&#xff0c;常用在学校超市&#xff0c;放在桌子上使用的&#xff0c;这2款消费机是迪科畅销机型&#xff0c;如下图 机器质量可靠稳定&#xff0c;不少用户使…

vivado产生报告阅读分析19-设计收敛报告

Challenging Timing Paths “ Challenging Timing Paths ” &#xff08; 时序收敛困难的路径 &#xff09; 部分列出了“ Assessment Details ” &#xff08; 评估详情 &#xff09; 部分中未能通过检查的时序路径的关键属性。默认情况下&#xff0c; 该命令会对每个时钟组中…

2024北京林业大学计算机考研分析

24计算机考研|上岸指南 北京林业大学 特色优势 Characteristics & Advantages&#xff1a;信息学院创建于2001年&#xff0c;是一个年轻而有朝气的学院。学院秉承“结构、特色、质量、创新”的八字方针&#xff0c;坚持以“质量提升、行业融合”为核心的内涵式发展战略&am…

在Linux上搭建JavaWeb项目运行环境

文章目录 安装JDK安装Tomcat安装数据库 安装JDK 安装Oracle官方的JDK比较麻烦&#xff0c;我们在此处选择安装开源社区维护的openjdk。他们俩的差别不大且兼容。 安装Tomcat 我们把本地下载好的 tomcat.zip 包拖到Linux页面上&#xff0c;让Linux也有一个zip包&#xff0c;再…

运动鞋品牌识别

一、前期工作 1. 设置GPU from tensorflow import keras from tensorflow.keras import layers,models import os, PIL, pathlib import matplotlib.pyplot as plt import tensorflow as tfgpus tf.config.list_physical_devices("GPU")if gpus:gpu0 …

网络安全工程师究竟是什么?怎么入门?

首先啊骚年们我们必须先了解网络安全这个行业究竟是干啥的。 是打ctf的&#xff1f;一个个都像韩商言吴白那么帅刷刷敲几个代码就能轻易夺旗&#xff1f; 还是像十大黑客之一的米特尼克一样闯入了“北美空中防务指挥系统”的计算机主机内&#xff0c;还在被通缉逃跑期间控制了…

【多线程】Thread类的使用

目录 1.概述 2.Thread的常见构造方法 3.Thread的几个常见属性 4.启动一个线程-start() 5.中断一个线程 5.1通过共享的标记来进行沟通 5.2 调用 interrupt() 方法来通知 6.等待一个进程 7.获取当前线程引用 8.线程的状态 8.1所有状态 8.2线程状态和转移的意义 1.概述 …

基于java技术的社区交易二手平台

基于java技术的社区交易二手平台的设计与实现 &#xff08;一&#xff09;开发背景 随着因特网的日益普及与发展&#xff0c;更多的人们开始通过因特网来寻求便利。但是&#xff0c;许多人都觉得网上商店里的东西不贵。所以&#xff0c;有些顾客宁愿去那些用二次定价建立起来的…

Relabel与Metic Relabel

Prometheus支持多种方式的自动发现目标&#xff08;targets&#xff09;&#xff0c;以下是一些常见的自动发现方式&#xff1a; 静态配置&#xff1a;您可以在Prometheus配置文件中直接列出要监测的目标。这种方式适用于目标相对稳定的情况下&#xff0c;例如固定的服务器或设…

【C++】泛型编程 ⑮ ( 类模板示例 - 数组类模板 | 自定义类中持有指针成员变量 )

文章目录 一、支持 数组类模板 存储的 自定义类1、可拷贝和可打印的自定义类2、改进方向3、改进方向 - 构造函数4、改进方向 - 析构函数5、改进方向 - 重载左移运算符6、改进方向 - 重载拷贝构造函数 和 等号运算符 二、代码示例1、Array.h 头文件2、Array.cpp 代码文件3、Test…