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

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的锁,导致了死锁。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

十八、初识elasticsearsh (索引)

目录 一、Elasticsearch的介绍&#xff1a; 二、正向索引和倒排索引 1、正向索引 2、倒排索引 3、索引(index) :相同类型的文档的集合 4、映射(mapping):索引中文档的字段约束信息&#xff0c;类似表的结构约束 一、Elasticsearch的介绍&#xff1a; Elasticsearch是一个…

计算机网络四大地址转换(IP,MAC、端口、域名)

计算机网络有四大地址&#xff0c;分别是 ip地址、 MAC地址、域名、端口 计算机网络地址 他们之间是如何转换&#xff0c;通过什么协议转换的 IP地址到MAC地址&#xff0c;通过ARP协议 MAC地址得到IP地址&#xff0c;通过RARP协议 通过域名的到IP地址 是通过DNS查询 端口是…

深度解读英伟达新一轮对华特供芯片H20、L20、L2的定位

大家好&#xff0c;我是极智视界&#xff0c;欢迎关注我的公众号&#xff0c;获取我的更多前沿科技分享 邀您加入我的知识星球「极智视界」&#xff0c;星球内有超多好玩的项目实战源码和资源下载&#xff0c;链接&#xff1a;https://t.zsxq.com/0aiNxERDq 因为一直从事 AI 工…

Linux——使用kill结束进程并恢复进程

目录 查看进程结束进程修复进程 查看进程 在linux中&#xff0c;关闭某进程之前先查看已经在运行的进程有哪些&#xff0c;使用下面命令查看&#xff1a; ps aux | grep -i apt 命令查看哪个进程正在使用 apt结束进程 结束某线程的命令为&#xff1a; sudo kill -9 PID 命令…

【LeetCode】每日一题 2023_11_25 二叉树中的伪回文路径(dfs,数组/位运算)

文章目录 刷题前唠嗑题目&#xff1a;二叉树中的伪回文路径题目描述代码与解题思路偷看大佬题解 结语 刷题前唠嗑 LeetCode&#xff1f;启动&#xff01;&#xff01;&#xff01; 这个月第一次周末早起~ 题目&#xff1a;二叉树中的伪回文路径 题目链接&#xff1a;1457. 二…

基于UI交互意图理解的异常检测方法

美团到店平台技术部/质量工程部与复旦大学周扬帆教授团队开展了科研合作&#xff0c;基于业务实际场景&#xff0c;自主研发了多模态UI交互意图识别模型以及配套的UI交互框架。 本文从大前端质量保障领域的痛点出发&#xff0c;介绍了UI交互意图识别的方法设计与实现。基于UI交…

类和对象(3)日期类的实现

日期类的实现 一&#xff0c;声明二&#xff0c;函数成员定义2.1构造函数2.2获取月份天数2.3比较运算符2.3.1等于和大于2.3.2其他 2.4计算运算符2.4.1 &&2.4.2-&&- 2.5日期-日期 一&#xff0c;声明 class Date { public:Date(int year 1, int month 1, int…

【鸿蒙应用ArkTS开发系列】- 云开发入门实战二 实现省市地区三级联动地址选择器组件(上)

目录 概述 云数据库开发 一、创建云数据库的对象类型。 二、预置数据&#xff08;为对象类型添加数据条目&#xff09;。 三、部署云数据库 云函数实现业务逻辑 一、创建云函数 二、云函数目录讲解 三、创建resources目录 四、获取云端凭据 五、导出之前创建的元数据…

Chatbot开发三剑客:LLAMA、LangChain和Python

聊天机器人&#xff08;Chatbot&#xff09;开发是一项充满挑战的复杂任务&#xff0c;需要综合运用多种技术和工具。在这一领域中&#xff0c;LLAMA、LangChain和Python的联合形成了一个强大的组合&#xff0c;为Chatbot的设计和实现提供了卓越支持。 首先&#xff0c;LLAMA是…

Netty实现websocket且实现url传参的两种方式(源码分析)

1、先构建基本的netty框架 再下面的代码中我构建了一个最基本的netty实现websocket的框架&#xff0c;其他个性化部分再自行添加。 Slf4j public class TeacherServer {public void teacherStart(int port) throws InterruptedException {NioEventLoopGroup boss new NioEve…

借助 XEOS V6, 农牧龙头企业实现原有存储的高效在线替换

面对旧有存储系统的应用不足&#xff0c;某大型现代农牧龙头企业采用了星辰天合的对象存储 XEOS V6 方案&#xff0c; 该方案以其卓越的技术架构和同城双活异地灾备的解决方案完整性&#xff0c;在无缝高效完成系统替换的同时&#xff0c;可以极大地提升系统的灵活性和业务的连…

VMware Workstation Pro 安装虚拟机,无法打开此虚拟机电源 因为它需要使用x86架构,架构冲突

本来我下的iso文件&#xff0c;可以看到他是64的&#xff0c;但是ubuntu没有86的&#xff0c;我只能去下载cenos的 用这个去安装虚拟机就好了

虹科Pico汽车示波器 | 汽车免拆检修 | 2011款瑞麒M1车发动机起动困难、加速无力

一、故障现象 一辆2011款瑞麒M1车&#xff0c;搭载SQR317F发动机&#xff0c;累计行驶里程约为10.4万km。该车因发动机起动困难、抖动、动力不足、热机易熄火等故障进厂维修。用故障检测仪检测&#xff0c;发动机控制单元&#xff08;ECU&#xff09;中存储有故障代码“P0340相…

0003Java程序设计-ssm基于微信小程序的家教信息管理系统

文章目录 摘要目 录系统实现开发环境 编程技术交流、源码分享、模板分享、网课分享 企鹅&#x1f427;裙&#xff1a;776871563 摘要 本文讲述了基于微信小程序的家教信息管理系统的设计与实现。结合线上管理的特点&#xff0c;分析了家教信息管理系统的现状&#xff0c;给出…

Shell编程基础 – 变量(Variables)

Shell编程基础 – 变量&#xff08;Variables&#xff09; Shell Scripting Essentials – Variables Bash变量作为shell脚本的重要组成部分&#xff0c;提供了在Unix/Linux命令行界面操作和保存数据的方法。 本文简要介绍Bash Shell脚本变量的基础知识以及应用&#xff0c;包…

Android Studio 显示build variants工具栏

工具栏&#xff1a; 如下图所示 依次点击View-->ToolWindows-->Build Variants。 在此记个笔记

Hadoop实践指南:揭秘HDFS元数据并解析案例

1.什么是元数据 元数据&#xff08;Metadata&#xff09;&#xff0c;描述数据的数据&#xff08;data about data&#xff09;。 1.1 HDFS元数据 元数据&#xff1a;关于文件或目录的描述信息&#xff0c;如文件所在路径、文件名称、文件类型等等&#xff0c;这些信息称为文…

【开源】基于JAVA的车险自助理赔系统

项目编号&#xff1a; S 018 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S018&#xff0c;文末获取源码。} 项目编号&#xff1a;S018&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 角色管理模块2.3 车…

如何在没有备份的情况下恢复 iPhone 上已删除的短信

要在没有备份的情况下恢复 iPhone 上已删除的消息&#xff0c;您可以从“消息”应用程序恢复它们或使用第三方数据恢复工具。 虽然我们的 iPhone 可以做很多事情&#xff0c;但我在设备上最常做的事情之一就是文本。无论我是与朋友或家人联系&#xff0c;还是分享重要信息&…

从Redis反序列化UserDetails对象异常后发现FastJson序列化的一些问题

最近在使用SpringSecurityJWT实现认证授权的时候&#xff0c;出现Redis在反序列化userDetails的异常。通过实践发现&#xff0c;使用不同的序列化方法和不同的fastJson版本&#xff0c;异常信息各不相同。所以特地记录了下来。 一、项目代码 先来看看我项目中redis相关配置信息…