Java監控工具VisualVM

目錄

  • 一、簡介
  • 二、內存分析
    • 1、Heap堆
  • 三、CPU分析
  • 四、線程分析

一、簡介

VisualVM 是一款免費的,集成了多個JDK命令行工具的可視化工具,它能為您提供強大的分析能力,對Java應用程序做 性能分析和調優 。這些功能包括 生成和分析海量數據跟蹤內存泄漏監控垃圾回收器執行內存和CPU分析。本文主要介紹如何使用VisualVM進行性能分析及調優。

自從JDK 6 Update 7 以后已經作為Oracle JDK的一部分,位于JDK根目錄的bin文件夾下,無需安裝,直接運行即可。

在這里插入圖片描述

JDK路徑查看:


  • MAC查找JDK的路徑

  • Windows查找JDK的路徑


二、內存分析

VisualVM通過檢測JVM中加載的類和對象信息等幫助我們分析內存使用情況,我們可以通過VisualVM的監視標簽對應用程序進行內存分析。

1、Heap堆

首先寫一個內存堆占用較大的例子,代碼如下:

public class Main {public final static int OUTOFMEMORY = 200000000;public static String oom;public static StringBuffer tempOOM = new StringBuffer();public static void main(String[] args){threadHeap(OUTOFMEMORY);}public static void threadHeap(final int len){Thread t = new Thread(new Runnable() {@Overridepublic void run() {int i = 0;while(i < len){i++;try{tempOOM.append("abcdefghijabcdefghijabcdefghijabcdefghijabcdefghij");if(i%1000 == 1){Thread.sleep(10);}//Thread.sleep(1);} catch (Exception e){e.printStackTrace();break;} catch (Error e){e.printStackTrace();break;}}oom = tempOOM.toString();System.out.println("Thread Heap Length : " + oom.length());}});t.setName("ThreadHeap_1");t.start();}
}

運行該段代碼,然后查看VisualVM Monitor(監視), 堆內存會慢慢變大。

在這里插入圖片描述
在程序運行結束之前, 點擊 堆Dump 按鈕, 等待一會兒,得到dump結果,可以看到一些摘要信息。

點擊類, 發現char[]所占用的內存是最大的。
在這里插入圖片描述
雙擊 char[] ,得到如下實例數結果。
在這里插入圖片描述
StringBuffer類型的全局變量 tempOOM 占用內存特別大, 注意局部變量是無法通過堆dump來得到分析結果的

另外,對于 堆 dump 來說,在遠程監控jvm的時候,VisualVM是沒有這個功能的,只有本地監控的時候才有

三、CPU分析

CPU 性能分析的主要目的是統計函數的調用情況及執行時間,或者更簡單的情況就是統計應用程序的 CPU 使用情況。

沒有程序運行時的 CPU 使用情況如下圖:
在這里插入圖片描述
運行一段 占用CPU 的小程序,代碼如下:

public class Main {public static void main(String[] args){cpuFix();}public static void cpuFix(){try{// 80%的占有率int busyTime = 8;// 20%的占有率int idelTime = 2;// 開始時間long startTime = 0;while (true) {// 開始時間startTime = System.currentTimeMillis();/** 運行時間*/while (System.currentTimeMillis() - startTime < busyTime) {;}// 休息時間Thread.sleep(idelTime);}}catch(Exception ex){ex.printStackTrace();}}
}

結果如下:
在這里插入圖片描述
過高的 CPU 使用率可能是由于我們的項目中存在低效的代碼;

在我們對程序施壓的時候,過低的 CPU 使用率也有可能是程序的問題。

點擊【抽樣器】, 點擊【CPU】按鈕, 啟動CPU性能分析會話,VisualVM 會檢測應用程序所有的被調用的方法,在【CPU 樣例】下可以看到我們的方法cpuFix() 的自用時間最長, 如下圖:
在這里插入圖片描述
切換到【線程 CPU 時間】頁面下,我們的 main 函數這個進程占用CPU時間最長, 如下圖:
在這里插入圖片描述

四、線程分析

Java 語言能夠很好的實現多線程應用程序。當我們對一個多線程應用程序進行調試或者開發后期做性能調優的時候,往往需要了解當前程序中所有線程的運行狀態,是否有死鎖、熱鎖等情況的發生,從而分析系統可能存在的問題。

在 VisualVM 的監視標簽內,我們可以查看當前應用程序中所有實時線程(Live threads)和守護線程(Daemon threads)的數量等實時信息。

運行一段小程序,代碼如下:

public class Main {public static void main(String[] args){startThread("Thread_1");startThread("Thread_2");}public static void startThread(String threadName){Thread thread = new Thread(new Runnable() {@Overridepublic void run() {while (true){}}});thread.setName(threadName);thread.start();}
}

在這里插入圖片描述
VisualVM 的線程標簽提供了三種視圖,默認會以時間線的方式展現, 如下圖:

可以看到兩個我們run的程序里啟的線程:Thread_1 和 Thread_2。

在這里插入圖片描述
再來一段死鎖的程序,看VisualVM 能否分析出來:

public class Main {public static void main(String[] args){diethread();}public static void diethread(){DieThread d1=new DieThread(true);DieThread d2=new DieThread(false);final Thread t1 = new Thread(d1);final Thread t2 = new Thread(d2);t1.setName("DieThread_1");t2.setName("DieThread_2");t1.start();t2.start();}
}package com.javaagent.thread;public class DieThread implements Runnable {public static Object obj1=new Object();public static Object obj2=new Object();private boolean flag;public DieThread(boolean bl){flag = bl;}@Overridepublic void run() {if(flag) {while(true) {synchronized(obj1) {try {Thread.sleep(1000);}catch (InterruptedException e){e.printStackTrace();}System.out.println("線程" + Thread.currentThread().getName() + "獲取obj1鎖對象,等待獲取obj2鎖對象...");synchronized(obj2) {System.out.println(Thread.currentThread().getName() + " ---- obj2.");}}}}else {while(true){synchronized(obj2) {System.out.println("線程" + Thread.currentThread().getName() + "獲取obj2鎖對象,等待獲取obj1鎖對象...");synchronized(obj1) {System.out.println(Thread.currentThread().getName() + " ---- obj1.");}}}}}
}

打開VisualVM檢測到的JVM進程,我們可以看到這個tab在閃,VisualVM已經檢測到死鎖。

另外可以點擊【線程 Dump】線程轉儲,進一步分析。
線程
線程死鎖堆棧

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/446853.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/446853.shtml
英文地址,請注明出處:http://en.pswp.cn/news/446853.shtml

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

相關文章

對官方Mutexes的翻譯

參考鏈接 參考鏈接 Mutexes Whats A Mutex?Mutex OperationsBoost.Interprocess Mutex Types And HeadersScoped lockAnonymous mutex exampleNamed mutex example Whats A Mutex? 互斥是相互排斥的意思&#xff0c;它是進程之間最基本的同步形式。互斥保證只有一個線程可…

計算機應用基礎

計算概論知識點 1.計算機之父&#xff1a;馮.諾伊曼 計算機基本組成&#xff1a;運算器&#xff0c;控制器&#xff0c;存儲器&#xff0c;輸入設備&#xff0c;輸出設備 2.幾種計算機&#xff1a;臺式計算機,筆記本式計算機,PC服務器,平板式計算機… 3.電腦的硬件&#xff1a;…

Android最全UI庫合集

目錄抽屜菜單ListViewWebViewSwitchButton按鈕點贊按鈕進度條TabLayout圖標下拉刷新ViewPager圖表(Chart)菜單(Menu)浮動菜單對話框空白頁滑動刪除手勢操作RecyclerViewCardColorDrawableSpinner布局模糊效果TabBarAppBar選擇器(Picker)跑馬燈日歷時間主題樣式ImageView通知聊天…

對于boost鎖機制結論性的介紹

Conditions Whats A Condition Variable?Boost.Interprocess Condition Types And HeadersAnonymous condition example Whats A Condition Variable? 在前面的例子中&#xff0c;一個mutex被用來鎖定&#xff0c;但我們不能用它來有效地等待&#xff0c;直到滿足繼續的條件…

C++數據類型

C 數據類型 |–基本數據類型: 整型 short短整型 2 int基本整型4 long長整型 8 浮點型 float單精度型 4 double雙精度型 8 long double長雙精度型 16 字符型 char 1 邏輯型 bool 1 空類型 void |–構造類型 數組類型 構造體類型 struct 共用體類型 union 枚舉類型 enum 類類型…

Android Gradle 多渠道打包、動態配置AppName

目錄一、簡介二、Gradle多渠道打包1、普通做法2、Gradle多渠道打包一、簡介 因為國內Android應用分發市場的現狀&#xff0c;我們在發布APP時&#xff0c;一般需要生成多個渠道包&#xff0c;上傳到不同的應用市場。這些渠道包需要包含不同的渠道信息&#xff0c;在APP和后臺交…

boost鎖機制中Semaphores的介紹

結構 Whats A Semaphore?Boost.Interprocess Semaphore Types And HeadersAnonymous semaphore example Whats A Semaphore? 旗語是一種基于內部計數的進程間同步機制&#xff0c;它提供了兩種基本操作。等待&#xff1a;測試旗語數的值&#xff0c;如果小于或等于0&#x…

Android Gradle 批量修改生成的apk文件名

目錄一、簡介二、代碼實現1、 Gradle 3.0以下版本2、Gradle 3.0以上版本一、簡介 平時開發都知道&#xff0c;我們要上線的時候需要在Android studio打包apk文件&#xff0c;可是默認的打包名是app-release.apk或者app-debug.apk這樣的名字&#xff0c;太沒有辨識度了。 下面…

C++boost Class named_condition翻譯

Class named_condition boost::interprocess::named_condition 簡介 // In header: <boost/interprocess/sync/named_condition.hpp>class named_condition { public:// construct/copy/destructnamed_condition(create_only_t, const char *, const permissions &…

Android Studio 代理設置以及代理完全清除

目錄一、代理設置二、代理完全清除一、代理設置 首先我們來看下怎樣設置代理&#xff0c;Mac下打開【Preferences…】&#xff0c;然后搜索"HTTP"&#xff0c;選擇【HTTP Proxy】&#xff0c;按圖中設置配置好后&#xff0c;點擊【Apply】&#xff0c;然后在點擊【O…

安卓布局位置,dp與px的區別

手機6寸—指對角線 布局位置 橫軸—x軸 縱軸—y軸 一個像素點 dp與Px dp:設備無關像素,與像素密度相關,像素距離 dpi:像素密度,每英寸包含的像素數 px:屏幕上一個物理像素點 ldpi低密度 1dp0.75px mdpi中密度 1dp1px hdpi高密度 1dp1.5px xhdpi超高密度 1dp2px xxhdpi超…

Android Studio 快捷鍵大全(Mac系統)

目錄一、Mac上的按鍵符號二、快捷鍵查找/查看相關控制操作相關代碼重構相關一、Mac上的按鍵符號 符號說明?option / alt?shift?control?command?esc 二、快捷鍵 查找/查看相關 快捷鍵說明雙擊 shift搜索任意內容command F / command R當前文件查找/替換&#xff0c;使…

ubuntu下clion軟件連接boost庫文件

整體配置 cmake_minimum_required(VERSION 3.17) project(mutex_learn)set(CMAKE_CXX_STANDARD 14) #boost庫所在的根目錄set(BOOST_ROOT "/usr/local/include/boost") #添加頭文件搜索路徑 include_directories(/usr/local/include) #添加庫文件搜索路徑 link_dir…

Android程序結構

Project方式 .gradle文件夾:編譯相關生成 .idea文件夾:idea生成 app文件夾----應用程序的源代碼和資源 build----編譯后的文件存放的位置,最終apk文件存放的位置 libs:存放.jar和.so文件 src:AndroidTest與test存放測試相關的內容 main中Java文件夾存放Java源碼,res文件…

通過Github創建Android庫供其他項目依賴引用

目錄一、簡介二、實現第一步&#xff1a;將自己的項目托管到Github上。第二步&#xff1a;點擊releases。第三步&#xff1a;創建release。第四步&#xff1a;填寫版本號、名稱、描述信息。第五步&#xff1a;點擊【Publish release】。第六步&#xff1a;復制項目路徑。第七步…

使用boost模板函數實現讀寫鎖

介紹 shared_mutex即讀寫鎖&#xff0c;不同與我們常用的獨占式鎖mutex&#xff0c;shared_mutex是共享與獨占共存的鎖&#xff0c;實現了讀寫鎖的機制&#xff0c;即多個讀線程一個寫線程&#xff0c;通常用于對于一個共享區域的讀操作比較頻繁&#xff0c;而寫操作比較少的情…

安卓內邊距padding與外邊距magrin

內邊距padding與外邊距margin 內邊距只有容器才有,即里面要有視圖 具體示例

Android Studio發布項目到jcenter

目錄一、創建Bintray賬戶及Maven倉庫二、上傳項目到jcenter1、配置Android項目2、Gradle命令上傳3、在項目中引用4、Add to JCenter三、Demo示例一、創建Bintray賬戶及Maven倉庫 1、打開Bintray首頁&#xff0c;點擊 For an Open Source Account &#xff0c;快速注冊或者用第…

C++讀取文件,將文件內容讀到string字符串里面

使用stringstream和ifstream實現 代碼 std::ifstream f{file_name, std::ios::binary};std::stringstream ss;ss << f.rdbuf();auto data ss.str();