如何通過代碼監控JVM的運行狀態


一、背景

工作中我們需要對自己負責的系統的運行狀態進行監控,這個通常會使用公司內部的監控系統。我本來是沒想太多的,但有次無意中了解到公司對於GC次數時間的監控居然是自己寫程序解析JVM的gc日志,這讓我有點大吃一驚,我雖然知道JVM對外提供了接口獲取各種信息,但當時又一下子想不起來叫什么名字,怎么用,於是決定總結一下這塊東西,寫個Demo記下來便於以后使用是查看。

二、解決方案

其實要獲取JVM運行時的各項指標非常簡單,只需要調用JVM提供的接口進行獲取就好,核心類名叫做ManagementFactory,下面一一介紹一下。

1.JVM啟動參數

System.out.println("===============程序運行參數=================="); RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean(); //JVM啟動參數 System.out.println(runtimeMXBean.getInputArguments()); //系統屬性 System.out.println(runtimeMXBean.getSystemProperties()); //JVM名字 System.out.println(runtimeMXBean.getVmName()); 

2.線程狀態

System.out.println("===============線程狀態======================="); ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); //獲取當前JVM內的線程數量,該指標非常重要。 //之前遇到過用為沒有對該指標進行監控而導致問題無法及時定位的情況。 System.out.println(threadMXBean.getThreadCount()); System.out.println(threadMXBean.getCurrentThreadCpuTime()); System.out.println(threadMXBean.getCurrentThreadUserTime()); 

3.類加載情況

System.out.println("===============類加載狀態============================"); ClassLoadingMXBean classLoadingMXBean = ManagementFactory.getClassLoadingMXBean(); //獲取當前JVM加載的類數量 System.out.println(classLoadingMXBean.getLoadedClassCount()); //獲取JVM總加載的類數量 System.out.println(classLoadingMXBean.getTotalLoadedClassCount()); //獲取JVM卸載的類數量 System.out.println(classLoadingMXBean.getUnloadedClassCount()); 

4.系統狀態

System.out.println("================系統狀態======================"); OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean(); //獲取服務器的CPU個數 System.out.println(operatingSystemMXBean.getAvailableProcessors()); //獲取服務器的平均負載。這個指標非常重要,它可以有效的說明當前機器的性能是否正常,如果load過高,說明CPU無法及時處理任務。 System.out.println(operatingSystemMXBean.getSystemLoadAverage()); 

5.總內存內存使用狀態

System.out.println("================內存狀態==========================="); MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean(); //獲取堆內存使用情況,包括初始大小,最大大小,已使用大小等,單位字節 System.out.println(memoryMXBean.getHeapMemoryUsage().toString()); //獲取堆外內存使用情況。 System.out.println(memoryMXBean.getNonHeapMemoryUsage().toString()); 

6.各個內存區使用狀態

System.out.println("================堆內存狀態======================"); //這里會返回老年代,新生代等內存區的使用情況,按需自取就好 List<MemoryPoolMXBean> memoryPoolMXBeans = ManagementFactory.getMemoryPoolMXBeans(); memoryPoolMXBeans.forEach((pool) -> { System.out.println(pool.getName()); System.out.println(pool.getUsage()); }); 輸出結果: ================堆內存狀態====================== Code Cache init = 2555904(2496K) used = 1497216(1462K) committed = 2555904(2496K) max = 251658240(245760K) Metaspace init = 0(0K) used = 4513312(4407K) committed = 5111808(4992K) max = -1(-1K) Compressed Class Space init = 0(0K) used = 513592(501K) committed = 655360(640K) max = 1073741824(1048576K) PS Eden Space init = 8388608(8192K) used = 4191808(4093K) committed = 8388608(8192K) max = 8388608(8192K) PS Survivor Space init = 1048576(1024K) used = 0(0K) committed = 1048576(1024K) max = 1048576(1024K) PS Old Gen init = 10485760(10240K) used = 0(0K) committed = 10485760(10240K) max = 20971520(20480K) 

6.GC狀態
JVM啟動參數:-server -Xmx30m -Xms20m -Xmn10m -XX:+UseParNewGC
-XX:+UseConcMarkSweepGC

System.out.println("===============GC狀態=========================="); List<GarbageCollectorMXBean> garbageCollectorMXBeans = ManagementFactory.getGarbageCollectorMXBeans(); garbageCollectorMXBeans.forEach(collector -> { System.out.println(collector.getName()); System.out.println(collector.getCollectionCount()); System.out.println(collector.getCollectionTime()); }); 輸出結果: ===============GC狀態========================== ParNew 12 24 ConcurrentMarkSweep 24 225 

三、總結

有了這些基礎數據以后就可以監控我們的系統運行狀態,比如說起一個daemon線程,每秒中統計一下數據,有問題就報警。分布式系統的話可以定時上報系統的運行狀態然后再進行匯總監控。



作者:凌風郎少
鏈接:https://www.jianshu.com/p/978522f88ad0
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM