Java-性能分析和監(jiān)控工具深入詳解
Java監(jiān)控和管理
Java監(jiān)控和管理API
Java Standard Edition(Java SE)平臺提供的監(jiān)控和管理技術(shù) - JMX(Java Management Extensions) 技術(shù)。
Java SE 中包含了用于監(jiān)控和管理的(java.lang.management)API,通過這些 API 可以實現(xiàn)應(yīng)用程序的自我監(jiān)控,此 API 主要提供了以下信息的訪問:
- 類加載相關(guān)。
- JVM 相關(guān),例如運行時間、系統(tǒng)環(huán)境變量、用戶輸入?yún)?shù)。
- 線程相關(guān),例如線程狀態(tài),線程的統(tǒng)計信息、線程的堆棧等。
- 內(nèi)存使用情況。
- GC 情況。
- 死鎖檢測。
- 操作系統(tǒng)信息。
Java 8的java.lang.management模塊:
ClassLoadingMXBean:用于 Java 虛擬機的類加載系統(tǒng)的管理接口。
CompilationMXBean:用于 Java 虛擬機的編譯系統(tǒng)的管理接口。
GarbageCollectorMXBean:用于 Java 虛擬機的垃圾回收的管理接口。
MemoryManagerMXBean:內(nèi)存管理器的管理接口。
MemoryMXBeanJava :虛擬機的內(nèi)存系統(tǒng)的管理接口。
MemoryPoolMXBean:內(nèi)存池的管理接口。
OperatingSystemMXBean:用于操作系統(tǒng)的管理接口,Java 虛擬機在此操作系統(tǒng)上運行。
RuntimeMXBeanJava :虛擬機的運行時系統(tǒng)的管理接口。
ThreadMXBeanJava :虛擬機線程系統(tǒng)的管理接口。
Java虛擬機的監(jiān)控
上面說到 Java SE 中已經(jīng)內(nèi)置了開箱即用的監(jiān)控和管理功能,通過這些功能可以實現(xiàn)程序的自我監(jiān)測,Java 默認已經(jīng)實現(xiàn)了對 Java 虛擬機相關(guān)信息的監(jiān)測。
下面通過一個簡單的示例,演示如何通過監(jiān)控管理 API 獲取系統(tǒng)信息、編譯器信息、內(nèi)存信息以及垃圾收集器信息。
public static void main(String[] args) { showJvmInfo(); showMemoryInfo(); showSystem(); showClassLoading(); showCompilation(); showThread(); showGarbageCollector(); showMemoryManager(); showMemoryPool(); } /** * Java 虛擬機的運行時系統(tǒng) */ public static void showJvmInfo() { RuntimeMXBean rtMxBean = ManagementFactory.getRuntimeMXBean(); System.out.println("Java 虛擬機的運行時系統(tǒng)(RuntimeMXBean):"); System.out.println("jvm vendor:" + rtMxBean.getVmVendor()); System.out.println("jvm name:" + rtMxBean.getVmName()); System.out.println("jvm version:" + rtMxBean.getVmVersion()); System.out.println("jvm bootClassPath:" + rtMxBean.getBootClassPath()); System.out.println("jvm start time:" + rtMxBean.getStartTime()); System.out.println("\n"); } /** * Java 虛擬機的內(nèi)存系統(tǒng) */ public static void showMemoryInfo() { MemoryMXBean memoryMxBean = ManagementFactory.getMemoryMXBean(); MemoryUsage heap = memoryMxBean.getHeapMemoryUsage(); System.out.println("Java 虛擬機的內(nèi)存系統(tǒng)(MemoryMXBean):"); System.out.println("Heap " + heap.toString()); System.out.println( "Heap" + " init:" + heap.getInit() + byte2Mb(heap.getInit()) + " used:" + byte2Mb(heap.getUsed()) + " committed:" + byte2Mb(heap.getCommitted()) + " max:" + byte2Mb(heap.getMax())); System.out.println("\n"); } private static String byte2Mb(long source) { return "(" + source / 1024 / 1024 + "mb)"; } /** * Java 虛擬機在其上運行的操作系統(tǒng) */ public static void showSystem() { OperatingSystemMXBean operatingSystemMxBean = ManagementFactory.getOperatingSystemMXBean(); System.out.println("Java 虛擬機在其上運行的操作系統(tǒng)(OperatingSystemMXBean):"); System.out.println("Architecture(操作系統(tǒng)架構(gòu)): " + operatingSystemMxBean.getArch()); System.out.println("Processors(Java虛擬機可用的處理器數(shù)): " + operatingSystemMxBean.getAvailableProcessors()); System.out.println("System name(操作系統(tǒng)名稱): " + operatingSystemMxBean.getName()); System.out.println("System version(操作系統(tǒng)版本): " + operatingSystemMxBean.getVersion()); System.out.println("Last minute load(最后一分鐘的系統(tǒng)負載平均值): " + operatingSystemMxBean.getSystemLoadAverage()); System.out.println("\n"); } /** * Java 虛擬機的類加載系統(tǒng) */ public static void showClassLoading() { ClassLoadingMXBean classLoadingMxBean = ManagementFactory.getClassLoadingMXBean(); System.out.println("Java 虛擬機的類加載系統(tǒng)(ClassLoadingMXBean):"); System.out.println("TotalLoadedClassCount(加載的類總數(shù)): " + classLoadingMxBean.getTotalLoadedClassCount()); System.out.println("LoadedClassCount(當前加載的類的數(shù)量)" + classLoadingMxBean.getLoadedClassCount()); System.out.println("UnloadedClassCount(卸載類的總數(shù)):" + classLoadingMxBean.getUnloadedClassCount()); System.out.println("\n"); } /** * Java 虛擬機的編譯系統(tǒng) */ public static void showCompilation() { CompilationMXBean compilationMxBean = ManagementFactory.getCompilationMXBean(); System.out.println("Java 虛擬機的編譯系統(tǒng)(CompilationMXBean):"); System.out.println("TotalCompilationTime(編譯時間(毫秒)):" + compilationMxBean.getTotalCompilationTime()); System.out.println("name(JIT編譯器的名稱):" + compilationMxBean.getName()); System.out.println("\n"); } /** * Java 虛擬機的線程系統(tǒng) */ public static void showThread() { ThreadMXBean threadMxBean = ManagementFactory.getThreadMXBean(); System.out.println("Java 虛擬機的線程系統(tǒng)(ThreadMXBean):"); System.out.println("ThreadCount(當前活動線程數(shù))" + threadMxBean.getThreadCount()); System.out.println("PeakThreadCount(峰值實時線程計數(shù))" + threadMxBean.getPeakThreadCount()); System.out.println("TotalStartedThreadCount(啟動的線程總數(shù))" + threadMxBean.getTotalStartedThreadCount()); System.out.println("DaemonThreadCount(當前活動后臺進程線程數(shù))" + threadMxBean.getDaemonThreadCount()); System.out.println("isSynchronizerUsageSupported(虛擬機是否支持監(jiān)視可下載同步器的使用情況)" + threadMxBean.isSynchronizerUsageSupported()); System.out.println("AllThreadIds(所有活動線程ID):" + JSON.toJSONString(threadMxBean.getAllThreadIds())); System.out.println("CurrentThreadUserTime(當前線程在用戶模式下執(zhí)行的CPU時間(以納秒為單位))" + threadMxBean.getCurrentThreadUserTime()); for (ThreadInfo threadInfo : threadMxBean.getThreadInfo(threadMxBean.getAllThreadIds(), 1)) { System.out.print(threadInfo.getThreadId() + threadInfo.toString()); } System.out.println("\n"); } /** * Java 虛擬機中的垃圾回收器。 */ public static void showGarbageCollector() { List<GarbageCollectorMXBean> collectorMxBeans = ManagementFactory.getGarbageCollectorMXBeans(); System.out.println("Java 虛擬機中的垃圾回收器(GarbageCollectorMXBean):"); for (GarbageCollectorMXBean collectorMxBean : collectorMxBeans) { System.out.println("name(垃圾收集器名稱):" + collectorMxBean.getName()); System.out.println("--CollectionCount:" + collectorMxBean.getCollectionCount()); System.out.println("--CollectionTime" + collectorMxBean.getCollectionTime()); System.out.println("\n"); } System.out.println("\n"); } /** * Java 虛擬機中的內(nèi)存管理器 */ public static void showMemoryManager() { List<MemoryManagerMXBean> memoryManagerMxBeans = ManagementFactory.getMemoryManagerMXBeans(); System.out.println("Java 虛擬機中的內(nèi)存管理器(MemoryManagerMXBean):"); for (MemoryManagerMXBean managerMxBean : memoryManagerMxBeans) { System.out.println("name(內(nèi)存管理器名稱):" + managerMxBean.getName()); System.out.println("--MemoryPoolNames:" + String.join(",", managerMxBean.getMemoryPoolNames())); System.out.println("\n"); } System.out.println("\n"); } /** * Java 虛擬機中的內(nèi)存池 */ public static void showMemoryPool() { List<MemoryPoolMXBean> memoryPoolMxBeans = ManagementFactory.getMemoryPoolMXBeans(); System.out.println("Java 虛擬機中的內(nèi)存池(MemoryPoolMXBean):"); for (MemoryPoolMXBean memoryPoolMxBean : memoryPoolMxBeans) { System.out.println("name:" + memoryPoolMxBean.getName()); System.out.println("--CollectionUsage:" + memoryPoolMxBean.getCollectionUsage()); System.out.println("--type:" + memoryPoolMxBean.getType()); System.out.println("\n"); } System.out.println("\n"); } }
輸出:
Java 虛擬機的運行時系統(tǒng)(RuntimeMXBean): jvm vendor:Oracle Corporation jvm name:Java HotSpot(TM) 64-Bit Server VM jvm version:25.221-b11 jvm bootClassPath:F:\opt\Java\jdk8\jre\lib\resources.jar;F:\opt\Java\jdk8\jre\lib\rt.jar;F:\opt\Java\jdk8\jre\lib\sunrsasign.jar;F:\opt\Java\jdk8\jre\lib\jsse.jar;F:\opt\Java\jdk8\jre\lib\jce.jar;F:\opt\Java\jdk8\jre\lib\charsets.jar;F:\opt\Java\jdk8\jre\lib\jfr.jar;F:\opt\Java\jdk8\jre\classes jvm start time:1673181328952 Java 虛擬機的內(nèi)存系統(tǒng)(MemoryMXBean): Heap init = 268435456(262144K) used = 4028824(3934K) committed = 257425408(251392K) max = 3791650816(3702784K) Heap init:268435456(256mb) used:(3mb) committed:(245mb) max:(3616mb) Java 虛擬機在其上運行的操作系統(tǒng)(OperatingSystemMXBean): Architecture(操作系統(tǒng)架構(gòu)): amd64 Processors(Java虛擬機可用的處理器數(shù)): 8 System name(操作系統(tǒng)名稱): Windows 10 System version(操作系統(tǒng)版本): 10.0 Last minute load(最后一分鐘的系統(tǒng)負載平均值): -1.0 Java 虛擬機的類加載系統(tǒng)(ClassLoadingMXBean): TotalLoadedClassCount(加載的類總數(shù)): 507 LoadedClassCount(當前加載的類的數(shù)量)507 UnloadedClassCount(卸載類的總數(shù)):0 Java 虛擬機的編譯系統(tǒng)(CompilationMXBean): TotalCompilationTime(編譯時間(毫秒)):8 name(JIT編譯器的名稱):HotSpot 64-Bit Tiered Compilers Java 虛擬機的線程系統(tǒng)(ThreadMXBean): ThreadCount(當前活動線程數(shù))5 PeakThreadCount(峰值實時線程計數(shù))5 TotalStartedThreadCount(啟動的線程總數(shù))5 DaemonThreadCount(當前活動后臺進程線程數(shù))4 isSynchronizerUsageSupported(虛擬機是否支持監(jiān)視可下載同步器的使用情況)true AllThreadIds(所有活動線程ID):[5,4,3,2,1] CurrentThreadUserTime(當前線程在用戶模式下執(zhí)行的CPU時間(以納秒為單位))234375000 5"Attach Listener" Id=5 RUNNABLE 4"Signal Dispatcher" Id=4 RUNNABLE 3"Finalizer" Id=3 WAITING on java.lang.ref.ReferenceQueue$Lock@17c68925 at java.lang.Object.wait(Native Method) - waiting on java.lang.ref.ReferenceQueue$Lock@17c68925 2"Reference Handler" Id=2 WAITING on java.lang.ref.Reference$Lock@7e0ea639 at java.lang.Object.wait(Native Method) - waiting on java.lang.ref.Reference$Lock@7e0ea639 1"main" Id=1 RUNNABLE at sun.management.ThreadImpl.getThreadInfo1(Native Method) Java 虛擬機中的垃圾回收器(GarbageCollectorMXBean): name(垃圾收集器名稱):PS Scavenge --CollectionCount:0 --CollectionTime0 name(垃圾收集器名稱):PS MarkSweep --CollectionCount:0 --CollectionTime0 Java 虛擬機中的內(nèi)存管理器(MemoryManagerMXBean): name(內(nèi)存管理器名稱):CodeCacheManager --MemoryPoolNames:Code Cache name(內(nèi)存管理器名稱):Metaspace Manager --MemoryPoolNames:Metaspace,Compressed Class Space name(內(nèi)存管理器名稱):PS Scavenge --MemoryPoolNames:PS Eden Space,PS Survivor Space name(內(nèi)存管理器名稱):PS MarkSweep --MemoryPoolNames:PS Eden Space,PS Survivor Space,PS Old Gen Java 虛擬機中的內(nèi)存池(MemoryPoolMXBean): name:Code Cache --CollectionUsage:null --type:Non-heap memory name:Metaspace --CollectionUsage:null --type:Non-heap memory name:Compressed Class Space --CollectionUsage:null --type:Non-heap memory name:PS Eden Space --CollectionUsage:init = 67108864(65536K) used = 0(0K) committed = 0(0K) max = 1399848960(1367040K) --type:Heap memory name:PS Survivor Space --CollectionUsage:init = 11010048(10752K) used = 0(0K) committed = 0(0K) max = 11010048(10752K) --type:Heap memory name:PS Old Gen --CollectionUsage:init = 179306496(175104K) used = 0(0K) committed = 0(0K) max = 2843738112(2777088K) --type:Heap memory Disconnected from the target VM, address: '127.0.0.1:12687', transport: 'socket' Process finished with exit code 0
Java監(jiān)控和管理工具
JMX 技術(shù)中提到 JMX 不僅提供了監(jiān)控和管理的 API ,還提供了用于網(wǎng)絡(luò)遠程管理的服務(wù),可以使用 JMX 相關(guān)監(jiān)控管理工具,通過網(wǎng)絡(luò)遠程連接到正在運行 Java 虛擬機,監(jiān)控其運行狀態(tài)。
JMC(Java Mission Control)
Java Mission Control使您能夠監(jiān)視和管理Java應(yīng)用程序,而不會引入通常與這些類型的工具相關(guān)聯(lián)的性能開銷。
它使用為Java虛擬機(JVM)的常規(guī)自適應(yīng)動態(tài)優(yōu)化收集的數(shù)據(jù)。
除了最小化性能開銷之外,這種方法還消除了觀察器效應(yīng)的問題,當監(jiān)視工具改變系統(tǒng)的執(zhí)行特性時會發(fā)生這種問題。
Java Mission Control由客戶端應(yīng)用程序(JMC客戶端)和在其上運行的許多插件組成:
- JVM Browser顯示正在運行的Java應(yīng)用程序及其JVM。每個JVM實例都稱為JVM連接。
- JMX Console連接到正在運行的JVM,實時收集和顯示其特征,并允許您通過Managed Beans(MBean)更改某些運行時屬性。您還可以創(chuàng)建觸發(fā)某些事件的規(guī)則(例如,如果應(yīng)用程序的CPU使用率達到90%,則發(fā)送電子郵件)。
- Java Flight Recorder(JFR)收集并保存詳細的性能特征,以進行歷史分析和分析。它可以用作獨立的性能監(jiān)視和分析工具,但是當用作JMC客戶端的插件時,它會在邏輯分組的表,圖表和撥號中顯示診斷信息。它使您可以選擇專注于問題所需的時間范圍和詳細程度。
- Java Mission Control插件使用Java Management Extensions(JMX)代理連接到JVM。
啟動JMC
雙擊JAvA_HOME\bin\jmc.exe 文件啟動JMC
連接遠程程序添加配置:
-Dcom.sun.management.jmxremote.port=7001 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=your ip
JMC功能介紹
MBean瀏覽器中查看類屬性信息:
內(nèi)存欄目查看GC、各個內(nèi)存區(qū)域使用情況:
線程狀態(tài)、死鎖、堆棧信息:
診斷命令,查詢vm信息等:
JFR(Java Flight Recorder)
黑匣子是用于記錄飛機飛行和性能參數(shù)的儀器。在飛機出問題后,用于定位問題原因。JFR 就是 Java 的黑匣子。
JFR 是 Java Flight Record (Java飛行記錄) 的縮寫,是 JVM 內(nèi)置的基于事件的JDK監(jiān)控記錄框架。
這個起名就是參考了黑匣子對于飛機的作用,將Java進程比喻成飛機飛行。
顧名思義,這個記錄主要用于問題定位和持續(xù)監(jiān)控。
如果是利用默認配置啟動這個記錄,性能非常高效,對于業(yè)務(wù)影響很小,因為這個框架本來就是用來長期在線上部署的框架。
這個記錄可以輸出成二進制文件,用戶可以指定最大記錄時間,或者最大記錄大小,供用戶在需要的時候輸出成文件進行事后分析。
JFR在Java應(yīng)用運行時收集對應(yīng)發(fā)生的事件,主要有三種類型的事件提供給JFR收集:
- 即時事件:一旦事件發(fā)生會立即進行數(shù)據(jù)記錄
- 持續(xù)事件:如果持續(xù)時間超過指定閾值則進行數(shù)據(jù)記錄
- 簡單事件:用于記錄應(yīng)用所在系統(tǒng)的活躍指標(例如CPU,內(nèi)存等)
開啟JFR記錄
通過啟動參數(shù)配置并且啟用 JFR,也可以通過啟動參數(shù)在 JVM 進程啟動的時候就啟動 JFR,或者是利用 jcmd 工具,動態(tài)啟用或者關(guān)閉 JFR。
JDK 8中的-XX:+FlightRecorder
java -XX:StartFlightRecording=disk=true,dumponexit=true,filename=recording.jfr,maxsize=1024m,maxage=1d,settings=profile,path-to-gc-roots=true test.Main
JConsole
Jconsole (Java Monitoring and Management Console),一種基于JMX的可視化監(jiān)視、管理工具。
JConsole 基本包括以下基本功能:概述、內(nèi)存、線程、類、VM概要、MBean。
概述
內(nèi)存
線程
可以看到線程列表、線程狀態(tài)、線程名稱、線程堆棧等信息。
類
可以看到 已加裝當前類、已加載類總數(shù)、已卸載類總數(shù)。
VM
MXBean
JVisualVM
VisualVM(All-in-One Java Troubleshooting Tool);功能最強大的運行監(jiān)視和故障處理程序。
功能描述:
- 顯示虛擬機進程以及進程的配置、環(huán)境信息(jps、jinfo)。
- 監(jiān)視應(yīng)用程序的CPU、GC、堆、方法區(qū)(1.7及以前),元空間(JDK1.8及以后)以及線程的信息(jstat、jstack)。
- dump以及分析堆轉(zhuǎn)儲快照(jmap、jhat)。
- 方法級的程序運行性能分析,找出被調(diào)用最多、運行時間最長的方法。
- 離線程序快照:收集程序的運行時配置、線程dump、內(nèi)存dump等信息建立一個快照。
Java Management Extensions(JMX)
以上就是Java-性能分析和監(jiān)控工具深入詳解的詳細內(nèi)容,更多關(guān)于Java-性能分析&監(jiān)控工具的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Spring Bean實例的創(chuàng)建及構(gòu)造器的挑選
這篇文章主要介紹了Spring Bean實例的創(chuàng)建及構(gòu)造器的挑選,文中有非常詳細的代碼示例,對正在學習java的小伙伴們有很好的幫助,需要的朋友可以參考下2021-04-04Java中常用的數(shù)據(jù)庫連接池_動力節(jié)點Java學院整理
數(shù)據(jù)庫連接池負責分配、管理和釋放數(shù)據(jù)庫連接,它允許應(yīng)用程序重復(fù)使用一個現(xiàn)有的數(shù)據(jù)庫連接,而不是再重新建立一個;釋放空閑時間超過最大空閑時間的數(shù)據(jù)庫連接來避免因為沒有釋放數(shù)據(jù)庫連接而引起的數(shù)據(jù)庫連接遺漏2017-08-08動態(tài)更改Spring定時任務(wù)Cron表達式的優(yōu)雅方案實例詳解
spring定時器非常強大,但是有時候我們需要在不需要重啟應(yīng)用就可以動態(tài)的改變Cron表達式的值,下面這篇文章主要給大家介紹了關(guān)于動態(tài)更改Spring定時任務(wù)Cron表達式的優(yōu)雅方案,需要的朋友可以參考下2022-12-12