啟動JMS服務
JConsole是從Java 5中開始引入的一個用於對JVM性能和資源消耗進行監控的圖形化工具。
JConsole可以連接本地的Java程序,也可以連接遠程的Java程序。由於是GUI的方式使用,所以就不細說那些基本的使用方法了,這里只是記錄一下試用過程中遇到的幾個小問題及其解決方案。
1. 要實現讓JConsole可以遠程連接到某個Java程序,則需要在Java程序啟動的JAVA_OPTION中添加選項“com.sun.management.jmxremote.port=8888”來指定遠程管理的端口。
2. 啟動Java程序時,遇到如下報錯:
Thu Jul 25 23:00:50 CST 2013 ./jbb.jar:./check.jar: java full version "1.6.0_24-b24" Error: Password file not found: /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/jre/lib/management/jmxremote.password Thu Jul 25 23:00:50 CST 2013
這是由於開啟Java JMX 遠程管理時,默認會有用戶名密碼的驗證,所以需要相應的密碼文件。
[root@localhost SPECjbb2005]# ls /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/jre/lib/management/ jmxremote.access jmxremote.password.template management.properties snmp.acl.template
需要先在jmxremote.access中定義用戶權限,然后在jmxremote.password文件中定義用戶名和對應的密碼,jmxremote.password文件可以復制jmxremote.password.template模板文件來進行修改。
當然,在內網中僅僅用於調試,我們一般可以不設置密碼驗證和SSL連接方式,Java選項如下:
-Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false
報錯:
Error: Password file read access must be restricted: /usr/java/jdk1.8.0_60/jre/lib/management/jmxremote.password
在配置JMX遠程訪問的時候,設置jmxremote.password文件權限,修改該文件時添加寫權限,chmod +w jmxremote.password ,放開角色信息那倆行的注釋,保存,再使用chmod 0400 jmxremote.password
這樣就是它正確的權限設置
jmxremote.password 在jdk/jre/lib/management/下,jmxremote.password.template復制,去掉.template后綴
3. 在進行了端口和認證信息的配置后,發現在JConsole中通過IP遠程連接JVM依然不成功。
錯誤信息為:Connection Failed: Retry? The connection to 192.168.52.11:8888 did not succeed. Would you like to try again?
在啟動Java時,需要設置RMI遠程調用的主機名,一般設置為主機的IP地址即可,如下:
-Djava.rmi.server.hostname=192.168.52.11
(當然,也有可能是由於前面第2點中提到的SSL的設置問題,依然需要檢查一下)
關於JConsole,還是得執行看看Oracle的這篇Java SE 6 中的JConsole的描述:
http://docs.oracle.com/javase/6/docs/technotes/guides/management/jconsole.html
(特別是上面文檔中對監控數據、圖形代表的意義是需要認真理解的)
Using JConsole
JConsole圖形用戶界面是符合Java Management Extensions(JMX)規范的監視工具。JConsole使用Java虛擬機(Java VM)的大量工具來提供有關在Java平台上運行的應用程序的性能和資源消耗的信息。
在Java平台標准版(Java SE平台)6中,JConsole已更新,以呈現Windows和GNOME桌面的外觀(其他平台將呈現標准的Java圖形外觀)。本文檔中提供的屏幕截圖取自在Windows XP上運行的界面實例。
Starting JConsole
jconsole可執行文件可以在JDK_HOME / bin中找到,其中JDK_HOME是Java開發工具包(JDK)的安裝目錄。如果此目錄位於系統路徑中,則只需在命令(shell)提示符下鍵入jconsole即可啟動JConsole。否則,您必須輸入可執行文件的完整路徑。
Command Syntax
您可以使用JConsole監視本地應用程序,即與JConsole在同一系統上運行的應用程序,以及遠程應用程序,即在其他系統上運行的應用程序。
注 - 使用JConsole監視本地應用程序對於開發和創建原型非常有用,但不建議在生產環境中使用,因為JConsole本身會消耗大量的系統資源。建議使用遠程監控將JConsole應用程序與正在監控的平台隔離。
有關jconsole命令的語法的完整參考,請參閱jconsole命令的手冊頁:Java監視和管理控制台。 Java Monitoring and Management Console.
Setting up Local Monitoring
Setting up Remote Monitoring
要啟動JConsole進行遠程監視,請使用以下命令語法:
% jconsole hostName:portNum
在上面的命令中,hostName是運行應用程序的系統的名稱,portNum是您在啟動Java VM時啟用JMX代理時指定的端口號。有關更多信息,請參閱遠程監視和管理。
如果您未指定主機名/端口號組合,則JConsole將顯示連接對話框(連接到JMX代理),以便您輸入主機名和端口號。
Viewing Overview Information
“Overview”(概覽)選項卡顯示關於CPU使用情況,內存使用情況,線程數量以及Java VM中加載的類的圖形化監視信息,所有這些都在一個屏幕中顯示。
“概覽”選項卡提供了一種簡單的方法,可以關聯之前僅通過在多個選項卡之間切換才可用的信息。
Saving Chart Data
JConsole允許您將圖表中顯示的數據保存為逗號分隔值(CSV)文件。要保存圖表中的數據,只需右鍵單擊任意圖表,選擇保存數據為...,然后指定將保存數據的文件。您可以通過這種方式保存JConsole不同選項卡中顯示的任何圖表中的數據。
CSV格式通常用於電子表格應用程序之間的數據交換。CSV文件可以導入到電子表格應用程序中,並可用於在這些應用程序中創建圖表。數據以兩個或多個命名列顯示,其中第一列代表時間戳。將文件導入電子表格應用程序后,通常需要選擇第一列,並根據需要將其格式更改為“日期”或“日期/時間”。
Monitoring Memory Consumption
“內存”選項卡提供有關內存消耗和內存池的信息。
“內存”選項卡具有“執行GC”按鈕,您可以隨時單擊執行垃圾回收。該圖表顯示了隨時間變化的Java VM的內存使用情況,堆內存和非堆內存以及特定內存池的使用情況。可用的內存池取決於正在使用哪個版本的Java VM。對於HotSpot Java VM,用於串行垃圾收集的內存池如下所示:
Eden Space (heap): 內存最初分配給大多數對象的池。
Survivor Space (heap): 包含在伊甸園空間的垃圾收集中存活的對象的池。
Tenured Generation(heap):包含已經存在一段時間的幸存者空間中的對象的池。
Permanent Generation (non-heap):包含虛擬機本身的所有反射數據(例如類和方法對象)的池。使用類數據共享的Java虛擬機,這一代分為只讀和讀寫區域。
Code Cache (non-heap): HotSpot Java VM還包含代碼緩存,其中包含用於編譯和存儲本機代碼的內存。
您可以通過選擇“圖表”下拉菜單中的選項來顯示不同的圖表,以繪制這些內存池的消耗情況。此外,單擊右下角的堆或非堆圖條會切換顯示的圖表。最后,您可以通過從“時間范圍”下拉菜單中的選項中進行選擇來指定跟蹤內存使用情況的時間范圍。
有關這些內存池的更多信息,請參閱下面的垃圾收集。
“詳細信息”區域顯示多個當前內存指標:
Used:當前使用的內存量,包括所有對象占用的內存,可達到和不可達。
Committed:保證可供Java VM使用的內存量。提交的內存量可能隨時間而改變。Java虛擬機可能會向系統釋放內存,並且提交的內存量可能會少於啟動時初始分配的內存量。提交的內存量總是大於或等於已用內存量。
Max:可用於內存管理的最大內存量。它的值可能會改變或者是未定義的。如果Java虛擬機嘗試增加使用的內存大於提交的內存,即使使用的數量小於或等於最大值(例如,當系統虛擬內存不足時),內存分配也可能會失敗。
GC time:垃圾收集的累積時間和總調用次數。它可能有多行,每行代表Java VM中使用的一個垃圾收集器算法。
右下角的條形圖顯示了堆和非堆內存中的內存池使用的內存。當使用的內存超過內存使用閾值時,條形會變成紅色。您可以通過MemoryMXBean的屬性設置內存使用率閾值。
Heap and Non-Heap Memory
Java VM管理兩種內存:堆和非堆內存,這兩種內存都是在Java VM啟動時創建的:
堆內存是Java VM為其分配所有類實例和數組的內存的運行時數據區域。堆可以是固定的或可變的大小。垃圾收集器是一個自動內存管理系統,為對象回收堆內存。
非堆內存包括在Java VM的內部處理或優化所需的所有線程和內存之間共享的方法區。它存儲每類結構,如運行時常量池,字段和方法數據以及方法和構造函數的代碼。方法區域在邏輯上是堆的一部分,但根據實現,Java VM可能不會垃圾收集或壓縮。像堆內存一樣,方法區域可以是固定或可變的大小。方法區域的內存不需要是連續的。
除了方法區域之外,Java VM可能需要內存來進行內部處理或優化,這也屬於非堆內存。例如,即時(Just-In-Time,JIT)編譯器需要內存來存儲從Java VM代碼轉換來的高性能的本地機器代碼。
Memory Pools and Memory Managers
內存池和內存管理器是Java VM內存系統的關鍵方面。
內存池表示Java VM管理的內存區域。Java虛擬機至少有一個內存池,它可能會在執行期間創建或刪除內存池。內存池可以屬於堆或非堆內存。
內存管理器管理一個或多個內存池。垃圾回收器是一種內存管理器,負責回收不可達對象所使用的內存。Java VM可能有一個或多個內存管理器。它可能會在執行期間添加或刪除內存管理器。一個內存池可以由多個內存管理器來管理。
Garbage Collection
垃圾收集(GC)是Java VM如何釋放不再被引用的對象占用的內存。通常將具有活動引用的對象視為“活着”,並且將不引用(或不可訪問)的對象視為“死亡”。垃圾收集是釋放死對象所使用的內存的過程。GC使用的算法和參數可能會對性能產生顯着影響。
Java HotSpot VM垃圾收集器使用分代GC。世代GC利用了大多數程序符合以下概括的觀察:
他們創建了很多壽命很短的對象,例如迭代器和局部變量。
他們創建了一些具有很長生命的對象,例如高級持久對象。
分代GC將內存分成幾代,並為每個分配一個或多個內存池。當一代人使用其分配的內存時,VM會在該內存池上執行部分GC(也稱為次要集合)來回收死對象所使用的內存。部分GC通常比FULL GC快得多。
Java HotSpot虛擬機定義了兩代:年輕一代(有時稱為“托兒所”)和老一代。年輕一代包括一個"Eden space"和兩個"survivor spaces."。VM最初將所有對象分配到Eden空間,大多數對象都在那里死掉。當它執行一個次要的GC時,虛擬機將所有剩余的對象從Eden空間移動到其中一個幸存者空間。虛擬機將生存空間足夠長的物體移動到老一代的“終身”空間。當終身代填滿時,有一個完整的GC通常要慢得多,因為它涉及所有的活物。永久生成包含虛擬機本身的所有反射數據,例如類和方法對象。
世代的默認排列如圖3-7所示:
如果垃圾收集器已成為瓶頸,則可以通過自定義生成大小來提高性能。使用JConsole,您可以通過嘗試使用垃圾收集器參數來調查性能指標的敏感性。有關更多信息,請參閱使用5.0 HotSpot VM調整垃圾回收。
Monitoring Thread Use
“線程”選項卡提供有關線程使用的信息。
左下角的線程列表列出了所有活動的線程。如果在“過濾器”字段中輸入字符串,則“線程”列表將僅顯示名稱中包含您輸入的字符串的線程。單擊“線程”列表中線程的名稱可顯示有關該線程的信息,包括線程名稱,狀態和堆棧跟蹤。
該圖表顯示了隨着時間的推移活動線程的數量。顯示兩行:
紅:峰值線程數 藍色:活線程數。
線程MXBean提供了線程選項卡未涵蓋的其他幾個有用的操作。
findMonitorDeadlockedThreads:檢測是否有任何線程在對象監視器鎖上死鎖。該操作返回一個死鎖的線程ID數組。
getThreadInfo:返回線程信息。這包括線程當前被阻塞的名稱,堆棧跟蹤和監視器鎖,以及哪個線程持有該鎖,以及線程爭用統計信息。
getThreadCpuTime:返回給定線程消耗的CPU時間
通過在MBeans樹中選擇Threading MXBean,可以通過MBeans選項卡訪問這些附加功能。這個MXBean列出了在被監控的Java VM中訪問線程信息的所有屬性和操作。請參閱監視和管理MBean。
Detecting Deadlocked Threads
要檢查你的應用程序是否已經遇到死鎖(例如,你的應用程序似乎掛起),可以通過單擊“檢測死鎖”按鈕來檢測死鎖的線程。如果檢測到任何死鎖的線程,則會顯示在“線程”選項卡旁邊的新選項卡中,如圖3-9所示。
“檢測死鎖”按鈕將檢測涉及對象監視器和java.util.concurrent可擁有同步器的死鎖周期(請參閱java.lang.management.LockInfo的API規范文檔)。在Java SE 6中添加了對java.util.concurrent鎖的監視支持。如果JConsole連接到J2SE 5.0 VM,則Detect Deadlock機制將僅查找與對象監視器相關的死鎖。JConsole不會顯示與可擁有的同步器相關的任何死鎖。
有關線程和守護進程線程的更多信息,請參閱java.lang.Thread的API文檔。
Monitoring Class Loading
類選項卡顯示有關類加載的信息。
圖表繪制了隨着時間的推移加載的類的數量。
紅線是加載的類的總數(包括隨后卸載的類)。
藍線是當前加載的類的數量。
選項卡底部的“詳細信息”部分顯示自Java VM啟動以來加載的類的總數,當前加載的編號和卸載的編號。您可以通過選中右上角的復選框來將類加載的跟蹤設置為詳細輸出。
Viewing VM Information
“VM摘要”選項卡提供有關Java VM的信息。
此選項卡中顯示的信息包括以下內容。
Summary
正常運行時間:Java VM啟動以來的總時間。
進程CPU時間:Java VM自啟動以來消耗的CPU時間總量。
總編譯時間:在JIT編譯中花費的總時間。Java VM確定何時發生JIT編譯。Hotspot虛擬機使用自適應編譯,其中VM使用標准解釋器啟動應用程序,然后在運行時分析代碼以檢測性能瓶頸或“熱點”。
Threads
活動線程:活動守護程序線程的當前數量加上非守護程序線程。
峰值:Java VM啟動以來的最大活動線程數
守護線程:當前的守護線程數量。
已啟動線程總數:Java VM啟動后啟動的線程總數,包括守護進程,非守護進程和終止線程。
Classes
當前加載的類:當前加載到內存中的類的數量。
加載的總類數:自Java VM啟動以來加載到內存中的類的總數,包括隨后被卸載的類。
卸載的總類數:自Java VM啟動以來從內存中卸載的類的數量。
Memory
當前堆大小:堆當前占用的千字節數。
提交內存:分配給堆使用的內存總量。
最大堆大小:堆占用的最大千字節數。
終止對象:終止對象的數量。
垃圾收集器:關於垃圾收集的信息,包括垃圾收集器名稱,執行的收集數量以及執行GC所花費的總時間。
Operating System
總物理內存:操作系統具有的隨機存取內存(RAM)的數量。
可用物理內存:可用於操作系統的可用RAM的數量。
提交的虛擬內存:保證可用於正在運行的進程的虛擬內存量。
Other Information
VM參數:應用程序傳遞給Java VM的輸入參數,不包括主方法的參數。
類路徑:系統類加載器用於搜索類文件的類路徑。
庫路徑:加載庫時要搜索的路徑列表。
引導類路徑:引導類加載器使用引導類路徑來搜索類文件。
Monitoring and Managing MBeans
“MBeans”選項卡以通用方式顯示有關在平台MBean服務器中注冊的所有MBean的信息。MBeans選項卡允許您訪問整套平台MXBean工具,包括在其他選項卡中不可見的工具。另外,您可以使用MBeans選項卡監視和管理應用程序的MBean。
左邊的樹顯示當前正在運行的所有MBean。當您在樹中選擇一個MBean,它的MBeanInfo和MBean描述都顯示在右側,和任何屬性,操作或通知出現在其下方的樹。
所有的平台MXBeans及其各種操作和屬性都可以通過JConsole的MBeans選項卡訪問。
Constructing the MBean Tree
默認情況下,MBean根據其對象名稱顯示在樹中。JConsole在將MBean添加到MBean樹時保留創建對象名稱時指定的關鍵屬性的順序。JConsole用於構建MBean樹的確切鍵屬性列表將是ObjectName.getKeyPropertyListString()方法返回的類型,第一個鍵為type,第二個鍵為j2eeType(如果存在)。
但是,當JConsole呈現MBean樹時,依賴於ObjectName關鍵屬性的默認順序有時會導致意外的行為。例如,如果兩個對象名稱具有相似的鍵,但鍵順序不同,則相應的MBean將不會在MBean樹中的同一節點下創建。
例如,假設您使用以下名稱創建Triangle MBean對象:
com.sun.example:type=Triangle,side=isosceles,name=1 com.sun.example:type=Triangle,name=2,side=isosceles com.sun.example:type=Triangle,side=isosceles,name=3
就JMX技術而言,這些對象將以完全相同的方式處理。對象名稱中鍵的順序與JMX技術沒有什么區別。但是,如果JConsole連接到這些MBean,並且使用默認的MBean樹渲染,那么對象com.sun.example:type = Triangle,name = 2,side = isosceles將最終創建在Triangle節點下的一個節點中稱為2,這又將包含一個稱為isosceles的子節點。另外兩個等腰三角形name = 1和name = 3將被組合在稱為isosceles的不同節點的Triangle下,如圖3-13所示