1. 程式人生 > >通過java程式碼獲取jvm資訊和系統資訊

通過java程式碼獲取jvm資訊和系統資訊

轉載自LOC_Thomas的部落格

前言

隨著微服務的概念逐漸流行,監控成了必不可少的模組,本篇文章主要介紹一下如何通過java程式碼獲得一些核心的資料,方便從各個方面對應用進行監控

獲取jvm資料

jvm資料是監控應用很重要的一系列引數,一般本地開發的時候可以通過jconsole來連到對應的程序上面,檢視相關指標資料,但是在線上環境就不適合通過jconsole來查看了, 所以我們現在使用通過java程式碼來獲得資料,然後上報出去,然後在外部通過展示。

那麼如何通過java程式碼來得到這些引數呢?

獲得jvm的堆記憶體程式碼

MemoryUsage heapMemoryUsage =
ManagementFactory.getMemoryMXBean().getHeapMemoryUsage(); System.out.println("jvm.heap.init is " + (heapMemoryUsage.getInit())); System.out.println("jvm.heap.used is " + (heapMemoryUsage.getUsed())); System.out.println("jvm.heap.committed is " + (heapMemoryUsage.getCommitted())); System.out.println
("jvm.heap.max is " + (heapMemoryUsage.getMax()));

獲得jvm的非堆記憶體程式碼

MemoryUsage nonHeapMemoryUsage = ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage();
System.out.println("jvm.nonheap.init is " + (nonHeapMemoryUsage.getInit()));
System.out.println("jvm.nonheap.used is " + (nonHeapMemoryUsage.
getUsed())); System.out.println("jvm.nonheap.committed is " + (nonHeapMemoryUsage.getCommitted())); System.out.println("jvm.nonheap.max is " + (nonHeapMemoryUsage.getMax()));

上面的方法只能得到jvm的堆和非堆的整體資料,一般都知道堆和非堆裡面都幾個不同的區,用來做不同功能,那麼如何得到不同區的資料呢?不多說,上程式碼

for (MemoryPoolMXBean pool : ManagementFactory.getMemoryPoolMXBeans()) {  
final String kind = pool.getType() == MemoryType.HEAP ? "heap" : "nonheap";  
final MemoryUsage usage = pool.getUsage();  
System.out.println("kind is " + kind + ", pool name is " + pool.getName() + ", jvm." + pool.getName() + ".init is " + usage.getInit());  
System.out.println("kind is " + kind + ", pool name is " + pool.getName() + ", jvm." + pool.getName() + ".used is " + usage.getUsed());  
System.out.println("kind is " + kind + ", pool name is " + pool.getName() + ", jvm." + pool.getName()+ ".committed is " + usage.getCommitted());  
System.out.println("kind is " + kind + ", pool name is " + pool.getName() + ", jvm." + pool.getName() + ".max is " + usage.getMax()); 
}

這樣就可以得到各種區的具體引數。

獲取作業系統引數

上面獲得了jvm的引數,但是還是需要監控機器的引數,如果想獲得機器的引數,僅僅通過jdk自帶的api要獲得,難度比較大,所以推薦使用一些開源的jar包。

大家比較熟悉的獲得作業系統的jar包是, sigar這個包, 但是我試用了一下, 覺得這個包太難用了。 不是指sigar的api難用,而是他獲得系統引數需要一些so檔案或者dll檔案,如果沒有的話,呼叫sigar的api時候會丟擲異常,所以要用起來還要去檢查這些檔案是否存在, 比較麻煩。

這個時候無意中發現了oshi這個包, 它不需要sigar所需要so或者dll檔案, 僅僅需要一個jna的包, 就可以了。所以我在pom.xml裡面加上了

<dependency>    
  <groupId>com.github.dblock</groupId>    
  <artifactId>oshi-core</artifactId>    
  <version>3.2</version>
</dependency>
<dependency>    
  <groupId>com.github.dblock</groupId>    
  <artifactId>oshi-json</artifactId>    
  <version>3.2</version>
</dependency>
<dependency>    
  <groupId>net.java.dev.jna</groupId>    
  <artifactId>jna-platform</artifactId>    
  <version>4.2.1</version>
</dependency>

然後通過oshi的api

SystemInfo si = new SystemInfo();
XXX xxx = si.getXXX();

這樣就可以輕鬆獲得系統各種引數了