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;}@Overridepublic 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.pswp.cn/news/167627.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/167627.shtml
英文地址,請注明出處:http://en.pswp.cn/news/167627.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

SpringBoot:異步任務基礎與源碼剖析

官網文檔&#xff1a;How To Do Async in Spring | Baeldung。 Async注解 Spring框架基于Async注解提供了對異步執行流程的支持。 最簡單的例子是&#xff1a;使用Async注解修飾一個方法&#xff0c;那么這個方法將在一個單獨的線程中被執行&#xff0c;即&#xff1a;從同步執…

系列六、Spring整合單元測試

一、概述 Spring中獲取bean最常見的方式是通過ClassPathXmlApplicationContext 或者 AnnotationConfigApplicationContext的getBean()方式獲取bean&#xff0c;那么在Spring中如何像在SpringBoot中直接一個類上添加個SpringBootTest注解&#xff0c;即可在類中注入自己想要測試…

java反序列化漏洞詳解

java反序列化漏洞 文章目錄 java反序列化漏洞漏洞原理漏洞評級漏洞危害漏洞驗證漏洞防御典型案例 漏洞原理 由于java開發人員在編寫代碼時重寫了 readObject 方法&#xff0c;在重寫的 readObject 方法中調用其他函數實現鏈式調用最終調用到了危險函數&#xff0c;從而形成反序…

【C++】泛型編程 ? ( 類模板示例 - 數組類模板 | 自定義類中持有指針成員變量 )

文章目錄 一、支持 數組類模板 存儲的 自定義類1、可拷貝和可打印的自定義類2、改進方向3、改進方向 - 構造函數4、改進方向 - 析構函數5、改進方向 - 重載左移運算符6、改進方向 - 重載拷貝構造函數 和 等號運算符 二、代碼示例1、Array.h 頭文件2、Array.cpp 代碼文件3、Test…

[網鼎杯 2020 朱雀組]phpweb

看一下源碼 應該是輸入的date 作為函數&#xff0c;value作為內部參數的值&#xff0c;將date()函數返回的結果顯示在頁面上 回去看的時候&#xff0c;意外發現頁面有了新的跳轉&#xff0c;觀察一下發現&#xff0c;頁面每隔五秒就會發生一次跳轉 所以就抓包看看 抓包發現po…

GEE:kNN(k-最近鄰)分類教程(樣本制作、特征添加、訓練、精度、最優參數、統計面積)

作者:CSDN @ _養樂多_ 本文將介紹在Google Earth Engine (GEE)平臺上進行kNN(k-最近鄰)分類的方法和代碼,其中包括制作樣本點教程(本地、在線和本地在線混合制作樣本點,合并樣本點等),加入特征變量(各種指數、紋理特征、時間序列特征、物候特征等),運行kNN(k-最近…

Linux中,查看Tomcat版本、如何查看Tomcat版本

方法 在tomcat的bin目錄下&#xff0c;執行version.sh命令即可 結果

python每日一題——3最長連續序列

題目 給定一個未排序的整數數組 nums &#xff0c;找出數字連續的最長序列&#xff08;不要求序列元素在原數組中連續&#xff09;的長度。 請你設計并實現時間復雜度為 O(n) 的算法解決此問題。 示例 1&#xff1a; 輸入&#xff1a;nums [100,4,200,1,3,2] 輸出&#xf…

RpcServiceContext上下文

消費者: web 提供者: buss-service 同一服務器: 192.168.100.228 RpcServiceContext serviceContext RpcContext.getServiceContext(); //web->buss-serviceLOGGER.warn("getRequest->{}", JsonUtil.toJson(serviceContext.getRequest())); //getRequest-…

ElementUI table+dialog實現一個簡單的可編輯的表格

table組件如何實現可編輯呢&#xff1f; 我的需求是把table組件那樣的表格&#xff0c;實現它點擊可以彈出一個框&#xff0c;然后在這個框里面輸入你的東西&#xff0c;然后將他回顯回去&#xff0c;當然&#xff0c;輸入的有可能是時間啥的。 為什么要彈出彈層不在框上直接…

最近iphone手機的交管12123閃退,打不開的解決辦法?

蘋果手機系統和新版軟件不配&#xff0c;終極決絕辦法&#xff1a;升級IOS系統就好 可能是手機的內存不足了&#xff0c;因為在使用APP時&#xff0c;需要占用手機的內存&#xff0c;如果手機內存不足以支持軟件允許&#xff0c;軟件就會閃退。車主可以清理一下手機的內存&…

彈窗msvcp140_1.dll丟失的解決方法,超簡單的方法分享

在計算機使用過程中&#xff0c;我們經常會遇到一些錯誤提示&#xff0c;其中最常見的就是缺少某個文件的錯誤。最近&#xff0c;我在使用某些軟件時&#xff0c;遇到了一個名為“msvcp140_1.dll”的錯誤提示。這個錯誤通常出現在運行某些程序時&#xff0c;由于缺少了msvcp140…

項目總結報告(案例模板)

軟件項目總結報告模板套用&#xff1a; 項目概要項目工作分析經驗與教訓改進建議可納入的項目過程資產 --------進主頁獲取更多資料-------

2023年【汽車駕駛員(中級)】最新解析及汽車駕駛員(中級)試題及解析

題庫來源&#xff1a;安全生產模擬考試一點通公眾號小程序 2023年汽車駕駛員&#xff08;中級&#xff09;最新解析為正在備考汽車駕駛員&#xff08;中級&#xff09;操作證的學員準備的理論考試專題&#xff0c;每個月更新的汽車駕駛員&#xff08;中級&#xff09;試題及解…

Doris中的物化視圖-查詢(十九)

物化視圖創建完成后&#xff0c;用戶的查詢會根據規則自動匹配到最優的物化視圖。 比如我們有一張銷售記錄明細表&#xff0c;并且在這個明細表上創建了三張物化視圖。一個存儲了不同時間不同銷售員的售賣量&#xff0c;一個存儲了不同時間不同門店的銷售量&#xff0c;以及每…

C#,《小白學程序》第二課:數組,循環與排序

1 什么是數組&#xff1f; 數組 Array 是一組數值&#xff08;數 或 值&#xff09;。 int[] a; int[,] b; int[][] c; Anything[] d; 都是數組。 2 排序 排序就是按大小、名字、拼音或你指定的信息進行比較后排隊。 排序是數組最基本的功能需求。 3 文本格式 /// <summa…

《數據結構、算法與應用C++語言描述》-代碼實現散列表(線性探查與鏈式散列)

散列表 完整可編譯運行代碼&#xff1a;Github:Data-Structures-Algorithms-and-Applications/_22hash/ 定義 字典的另一種表示方法是散列&#xff08;hashing&#xff09;。它用一個散列函數&#xff08;也稱哈希函數&#xff09;把字典的數對映射到一個散列表&#xff08…

spring-webflux的一些概念的理解

Spring5的webflux可以支持高吞吐量&#xff0c;使用相同的資源可以處理更加多的請求&#xff0c;它將會成為未來技術的趨勢&#xff0c;但是相對于學習其他的框架相比&#xff0c;它的學習曲線很高&#xff0c;綜合了很多現有的技術&#xff0c;即使按照教程學習能編寫代碼&…

requests庫的學習(詳細篇)

一、request庫的安裝 requests屬于第三方庫&#xff0c;Python不內置&#xff0c;因此需要我們手動安裝。 pip3 install requests

HTML5新特性

HTML5新特性 前言語義化標簽常用語義化標簽優點 新增input屬性新增type屬性值內容其他新增input屬性 video&#xff08;視頻&#xff09;與audio&#xff08;音頻&#xff09;標簽 前言 本文主要講解HTML5中新增了哪些內容。 語義化標簽 HTML5新增了語義化標簽這個特性&…