簡(jiǎn)介
jrockit jvm不只是快,它還和jrockit mission control一起,組成一套執(zhí)行運(yùn)行時(shí)分析和內(nèi)存泄漏檢測(cè)的分析工具,jrockit management console包含在jrockit jdk中。本文將探討jrockit management console的一種試驗(yàn)性的headless模式,它可以用于與來自命令行的基于jrockitjmx的管理代理進(jìn)行交互。ctrl-break handler提供了一種向jrockit發(fā)送各種高級(jí)命令的方法,甚至是在它啟動(dòng)后。這些命令甚至可以遠(yuǎn)程調(diào)用,我在后文中會(huì)提及。最后,我探討了試驗(yàn)性的code coverage,jrockit開箱即用地提供了該特性。
關(guān)于bea jrockit的更多信息,參見dev2dev網(wǎng)站的jrockit product center。
首先我將快速概述一下jrockit jvm可用的已確定的管理工具,然后我會(huì)轉(zhuǎn)向缺少文檔的試驗(yàn)性管理特性。
jrockit mission control
jrockit r26.0.0版本引入了jrockit mission control工具套件,它包含的工具可以進(jìn)行監(jiān)控、管理、分析和消除java應(yīng)用程序內(nèi)存泄漏,而不會(huì)引起通常與此類工具相關(guān)聯(lián)的性能開銷。mission control的低性能開銷是因?yàn)槭褂昧俗鳛閖rockit常規(guī)適應(yīng)性動(dòng)態(tài)調(diào)優(yōu)的一部分而收集的數(shù)據(jù),這還可以消除工具使用字節(jié)碼裝置修改系統(tǒng)執(zhí)行特性時(shí)發(fā)生heisenberg異常的問題。jrockit mission control功能可以根據(jù)需要隨時(shí)可用,低性能開銷也只在運(yùn)行工具時(shí)有效。這些特征使得jrockit mission control成為專門用于生產(chǎn)中系統(tǒng)的工具。
jrockit mission control中包含以下工具:
jrockit management consolejrockit management console用于監(jiān)控和管理多個(gè)jrockit實(shí)例。它捕獲并顯示關(guān)于垃圾收集器(gc)暫停、內(nèi)存和cpu使用的實(shí)時(shí)數(shù)據(jù),以及部署在jvm內(nèi)部mbean服務(wù)器上的所有jmx mbean的信息。jvm管理包括對(duì)cpu相似性、垃圾收集策略和內(nèi)存池大小的動(dòng)態(tài)控制。 jrockit runtime analyzer
jrockit runtime analyzer(jra)是一個(gè)隨需應(yīng)變的“動(dòng)態(tài)記錄器”,它生成關(guān)于jvm和正在運(yùn)行的應(yīng)用程序的詳細(xì)記錄。然后可以使用jra應(yīng)用程序?qū)τ涗浵聛淼呐渲梦募M(jìn)行離線分析。所記錄的數(shù)據(jù)包括對(duì)方法和鎖定的分析,還有垃圾收集統(tǒng)計(jì)信息,優(yōu)化決策以及對(duì)象統(tǒng)計(jì)信息。 jrockit memory leak detector
jrockit memory leak detector工具用來發(fā)現(xiàn)和查找內(nèi)存泄漏原因。memory leak detector的趨勢(shì)分析器可以發(fā)現(xiàn)非常緩慢的泄漏,顯示詳細(xì)的堆統(tǒng)計(jì)信息(包括指向泄漏對(duì)象和分配位置的引用類型和實(shí)例),并快速找出泄漏原因。memory leak detector使用先進(jìn)的圖形化表現(xiàn)技術(shù),以便更容易定位和理解有時(shí)比較復(fù)雜的信息。
關(guān)于jrockit mission control的更多信息,可以閱讀文章an introduction to jrockit mission control,或者訪問dev2dev網(wǎng)站的jrockit mission control。
jrockit management console的headless模式(試驗(yàn)性)
jrockit management console是監(jiān)控jrockit運(yùn)行的工具。它包括兩部分:一個(gè)運(yùn)行在jvm進(jìn)程中的jmx代理,一個(gè)使用圖形化用戶界面的獨(dú)立客戶端(關(guān)于它以及其它方面的更詳細(xì)的信息,請(qǐng)參見an introduction to jrockit mission control)。其中,用戶界面可以繪出部署在所連接的java虛擬機(jī)中的任何mbean的數(shù)值屬性的圖形。圖形密集的應(yīng)用程序?qū)Y源的消耗可能會(huì)相當(dāng)厲害,jrockit management console也不例外?梢砸雝ext-only(純文本)模式,以便使用management console的通知功能和數(shù)據(jù)收集工具而不會(huì)導(dǎo)致整個(gè)gui的開銷。
headless控制臺(tái)引入了大量新的命令行參數(shù)。這同樣適用于控制臺(tái)的gui版本。參數(shù)包括:
參數(shù)描述-headless以headless模式啟動(dòng)控制臺(tái)(不會(huì)加載與gui相關(guān)的類)。-settings <settings file>使用指定配置文件啟動(dòng)。如果以gui模式啟動(dòng),并且該文件不存在,那么它將在關(guān)閉management console時(shí)創(chuàng)建。-connectall連接配置文件中所有可用連接(即原先使用gui添加的)。-connect <connection 1> <connection 2> <...> 使用gui連接配置文件中可用的指定連接。-autoconnect自動(dòng)連接到運(yùn)行在啟用jrockit發(fā)現(xiàn)協(xié)議(jrockit discovery protocol,jdp)的管理服務(wù)器上的任何jrockit。-uptime <time in seconds>將控制臺(tái)運(yùn)行一段指定的時(shí)間,然后自動(dòng)關(guān)閉它。-useraction <name> <delay in seconds> <period (optional)>經(jīng)過指定的時(shí)延后運(yùn)行指定的用戶動(dòng)作。如果不指定period,動(dòng)作將只執(zhí)行一次;如果指定,動(dòng)作將每過<period>秒就執(zhí)行一次。-version打印management console的版本信息,并退出。-locale <language> <country (optional)>使用特定的地區(qū)啟動(dòng)控制臺(tái),比如,-locale ja jp將以日語啟動(dòng)控制臺(tái)(jrockit r27可用)。這里給出一個(gè)以headless模式啟動(dòng)management console的例子,讀取指定配置文件,嘗試連接所有已指定的jrockit,使用jrockit發(fā)現(xiàn)協(xié)議(jdp,下文討論)積極查找新的jrockit。30秒后將以每分鐘一次的間隔向所有連接的jrockit發(fā)送ctrl-break命令。一小時(shí)之后自動(dòng)關(guān)閉。以前加入指定連接的所有通知規(guī)則(不管是通過使用gui還是通過直接編輯配置文件添加的)將生效。
java -jar managementconsole.jar -headless -settings c:\headless\consolesettings.xml -connectall -autoconnect -uptime 3600 -useraction ctrlbreak 30 60用戶動(dòng)作是可以與jrockit management console上的一組連接進(jìn)行交互的插件類,同樣使用控制臺(tái)配置文件來存儲(chǔ)配置數(shù)據(jù)。用戶動(dòng)作顯示在jrockit控制臺(tái)圖形用戶界面的plugins菜單下,headless模式中也可用。隨控制臺(tái)提供了兩個(gè)默認(rèn)用戶動(dòng)作:jrarecording用戶動(dòng)作,對(duì)連接的jrockit啟動(dòng)jra記錄;ctrlbreak用戶動(dòng)作,向連接的jrockit發(fā)送ctrl-break命令(參見本文中關(guān)于ctrl-break handler和jrockit運(yùn)行時(shí)分析器的小節(jié))。要指定特定用戶動(dòng)作的參數(shù),可以使用gui進(jìn)行配置,也可以編輯management console配置文件,后者可以在<user.home>/managementconsole/managementconsole/consolesettings.<version>.xml文件中找到。
編寫自己的用戶動(dòng)作很容易。首先創(chuàng)建一個(gè)abstractuseraction的子類。該示例演示了如何創(chuàng)建一個(gè)從所有連接的jrockit獲取線程堆棧轉(zhuǎn)儲(chǔ)的用戶動(dòng)作。
package com.example.useractions;import java.io.ioexception;import java.util.list;import com.jrockit.console.rjmx.commonrjmxnames;import com.jrockit.console.rjmx.rjmxconnectormodel;import com.jrockit.console.useractions.abstractuseraction;/ * this is a simple user action, getting stackdumps from * the selected jrockits and printing them on stdout. * * @author marcus hirt */public class myuseraction extends abstractuseraction{ public void executeaction(list connections) { for (rjmxconnectormodel connection : connections) { if (connection.isconnected()) { try { system.out.println(commonrjmxnames.getthreadmxbean(connection).getthreadstackdump()); } catch (ioexception e) { e.printstacktrace(); } } } }}接下來,需要在consolesettings.xml文件中配置部屬描述符,以便用戶動(dòng)作對(duì)于控制臺(tái)可用?梢栽谂渲梦募邪l(fā)現(xiàn)user_actions元素,它已經(jīng)填充了一些user_action元素。示例動(dòng)作的部署描述符應(yīng)當(dāng)以相同的樣式輸入。描述符看起來會(huì)是這樣:
<user_action> <user_action_class>com.example.useractions.myuseraction</user_action_class> <user_action_name>stackdump</user_action_name> <user_action_menu_name>stack dump on stdout</user_action_menu_name> <user_action_description>gets a stack dump from the selected jrockit(s), and dumps it on stdout.</user_action_description></user_action>這也使得用戶動(dòng)作在plugins菜單下的用戶界面中可見。
當(dāng)控制臺(tái)啟動(dòng)或退出時(shí),如果有設(shè)置/狀態(tài)需要從配置文件加載/保存,只需重寫exporttoxml()/importfromxml()方法,如示例中所示:
/ * @see com.jrockit.console.util.xmlenabled * #exporttoxml(org.w3c.dom.element) */public void exporttoxml(element parentnode){ super.exporttoxml(parentnode); xmltoolkit.setsetting(parentnode, my_property, m_myval);}/ * @see com.jrockit.console.util.xmlenabled * #initializefromxml(org.w3c.dom.element) */ public void initializefromxml(element parentnode) { super.initializefromxml(parentnode); m_myval = xmltoolkit.getsetting(parentnode, my_property, default_my_value));}注意,用戶動(dòng)作的名稱是使用launcher啟動(dòng)參數(shù)時(shí)將引用的用戶動(dòng)作名稱,菜單名是會(huì)在gui菜單中顯示的名稱。更多的信息請(qǐng)參見user action docs和jlmext docs。注意,這只是一個(gè)試驗(yàn)性的功能,提供的文檔還相當(dāng)簡(jiǎn)單,編寫定制的通知?jiǎng)幼骱图s束的方式與此類似。更多信息請(qǐng)參見management console user guide。
jrockit發(fā)現(xiàn)協(xié)議(jdp)
jdp(jrockit發(fā)現(xiàn)協(xié)議)是個(gè)簡(jiǎn)單且有效的協(xié)議,用于允許jrockit管理服務(wù)器向management console組播它的存在。下面的兩個(gè)表分別列出了在服務(wù)器端和客戶端控制jdp行為的系統(tǒng)屬性。
管理服務(wù)器的jdp屬性 系統(tǒng)屬性描述默認(rèn)值jrockit.managementserver.autodiscovery 啟用jrockit發(fā)現(xiàn)協(xié)議falsejrockit.managementserver.discovery.period在兩個(gè)ping之間需要等待多久(以毫秒為單位)5000jrockit.managementserver.discovery.ttl活躍的躍點(diǎn)數(shù)1jrockit.managementserver.discovery.address所使用的組播地址232.192.1.212jrockit.managementserver.discovery.port所使用的組播端口7095
management console的jdp屬性 系統(tǒng)屬性描述默認(rèn)值com.jrockit.console.preferences.jdp.port用于jrockit發(fā)現(xiàn)協(xié)議的端口7095com.jrockit.console.preferences.jdp.address所使用的組播地址232.192.1.212
這里給出了在服務(wù)器端啟用jdp的情況下,啟動(dòng)jrockit需要最少參數(shù)的示例。
java -xmanagement -djrockit.managementserver.autodiscovery=true<your program>ctrl-break handler
您是否曾經(jīng)希望在jvm啟動(dòng)后可以使用一種輕松的方式與其交互?假如說您忘記添加-xmanagement選項(xiàng)來啟動(dòng)管理服務(wù)器,或者您想改變運(yùn)行系統(tǒng)中g(shù)c的冗余級(jí)別。這些現(xiàn)在很容易通過重新配置ctrl-break handler來完成,而且它不只是打印堆棧跟蹤。
用法 創(chuàng)建一個(gè)名為ctrlhandler.act的文件。 向ctrlhandler.act文件添加命令(參見下文命令列表)。 以“stop”結(jié)束文件,這是結(jié)束文件分析的保留命令。 按下ctrl-break,每一個(gè)命令都將以出現(xiàn)的順序執(zhí)行。jrockit首先會(huì)在當(dāng)前工作目錄查找該文件。如果未找到,jrockit將在jvm目錄中查找。如果仍然沒有的話,jrockit將回退以生成一個(gè)常規(guī)的線程堆棧轉(zhuǎn)儲(chǔ)。jrockit將在每次按下ctrl-break時(shí)讀取act文件,因此用戶可以在方便時(shí)重新配置該文件,而同時(shí)jrockit仍在運(yùn)行。
這里給出一個(gè)示例act文件,它首先打印時(shí)間戳,然后是用于啟動(dòng)jrockit的命令行,最后是一個(gè)線程堆棧轉(zhuǎn)儲(chǔ)。它還包括可以用于act文件的有用命令的列表:
# example ctrlhandler.act filetimestampcommand_lineprint_threadsstop# set_filename filename=<file> [append=true]# sets the file that all handlers following this command will# use for printing. you can have several set_filename commands# in a file. it takes two arguments: filename and an optional# append to specify if you want to append to the file # or overwrite it. default is to overwrite the file. # timestamp# prints a timestamp. # print_threads# the normal thread dump.# verbosity [args=<components>] [filename=<file>]# changes the verbosity level normally specified with -xverbose. # version# prints jrockit version information. # command_line# prints the command line used to start jrockit. # print_object_summary# prints heap usage statistics (how much heap is used per class),# together with a delta on how much this has changed since# the last invocation of this ctrl-break handler.# print_memusage# prints a memory usage report of how jrockit is using# the memory.# heap_diagnostics# prints a detailed report of the heap, including ascii graphics # over the heap layout.# print_class_summary# prints all loaded classes. # print_utf8pool# print all utf8 strings. # jrarecording [filename=<file>] [time=<time>] [nativesamples=true]# starts a jra recording.# run_optfile [filename=<file>]# see optfile. # start_management_server# starts the new jmx-based management agent. # kill_management_server# stops the management agent. # start_rmp_server# starts the old management server (actually the listening # socket that in turn starts servers whenever a connection# is established). # kill_rmp_server# stops the old management server (actually shuts down the# listening socket). the only reason it isn't named # kill_rmp_server is that stop is a reserved keyword # that stops the parsing of the act file. ;) # help [ctrl-break handler]# prints all available ctrl-break handlers if no argument # is specified, or help for the specified ctrl-break handler.# memleakserver [port=<port>]# toggles the memleakserver. if it hasn't been started # it will be started. if it has already started, it will be# shut down. the default port is 7095.# verbose_referents action=[heap|full|nursery|start|stop]# print verbose reference information.# parameters:# action=[heap|full|nursery|start|stop]# heap - trigger a heap collection and output reference# information# full - trigger a full heap collection (clears softly # reached soft referents)# nursery - trigger a nursery collection (heap collection # if running without nursery)# start - start writing reference information to default# verbose stream# stop - stop writing reference information# print_exceptions # exceptions=[true|all|false] stacktraces=[true|all|false]# enable printing of java exceptions thrown in the vm.# parameters:# exceptions - print exceptions# stacktraces - print exceptions with stacktraces# at least one of the parameters is required.# values for the parameters can be "true|all|false"# true - print all exceptions # except java/util/emptystackexception,# java/lang/classnotfoundexception and # java/security/privilegedactionexception# all - print all exceptions# false - don't print exceptions# to turn exception printing off completely you need to set# exceptions = false even if it was turned # on by stacktraces = true.jrcmd使用jrcmd實(shí)用工具是一種新的調(diào)用ctrl-break handler的便捷方式,可在jrockit發(fā)行版的bin目錄中找到它。用法jrcmd <pid> <command> <parameters>jrcmd
使用jrcmd實(shí)用工具是一種新的調(diào)用ctrl-break handler的便捷方式,可在jrockit發(fā)行版的bin目錄中找到它。
如果不指定選項(xiàng)(或者只指定-p),那么將顯示運(yùn)行在本地機(jī)器上的所有jrockit的進(jìn)程id。如果pid設(shè)為0,那么命令將發(fā)送給在本地機(jī)器上運(yùn)行的所有jrockit jvm。
要列出特定的jrockit中有哪些ctrl-break handler可用,可以使用help命令:
jrcmd <pid> help要想獲得某個(gè)具體的ctrl-break handler的幫助信息,需要在help后添加ctrl-break handler的名稱,比如:
jrcmd 0 help kill_management_server也可以使用jrcmd列出指定進(jìn)程的性能計(jì)數(shù):
jrcmd <pid> -l遠(yuǎn)程調(diào)用ctrl-break handler
可以使用jrockit management console來遠(yuǎn)程調(diào)用ctrl-break handler。存在一個(gè)對(duì)jrockitconsolembean的操作,稱為runctrlbreakhandlerwithresult。jrockit management console可以從屬性瀏覽器調(diào)用對(duì)mbean的操作。這里有關(guān)于如何調(diào)用ctrl-break handler的逐步描述。
試著輸入“help”作為參數(shù),將會(huì)列出所有可用的ctrl-break handler,如圖1所示。
圖1.從jrockit management console調(diào)用ctrl-break handler(單擊圖片查看大圖)
堆視圖(試驗(yàn)性)
當(dāng)分析應(yīng)用程序如何使用某種垃圾收集策略時(shí),在每一次gc后對(duì)堆進(jìn)行快照將會(huì)非常有幫助。這有助于開發(fā)人員研究數(shù)據(jù),比如碎片/壓縮以及算法通常如何執(zhí)行。但是快照中包含如此多的數(shù)據(jù)量以至于查看它沒有什么意義,因此jrockit團(tuán)隊(duì)開發(fā)了一個(gè)提供圖形化表示的小工具,以便更好地進(jìn)行說明。
圖2顯示了一個(gè)快照的例子(使用的是一個(gè)非常早的jrockit 1.4.2預(yù)發(fā)布版本):
每一排表示一次垃圾收集。左邊是開始的堆,右邊是結(jié)束的堆。堆顯示的右邊是一個(gè)可配置圖形。實(shí)心白色區(qū)域表示空白堆,黑色區(qū)域是充實(shí)區(qū)(也就是填充了對(duì)象的區(qū)域),淺灰色區(qū)域是碎片區(qū),紅色、黃色和綠色區(qū)域是可配置圖形。可以從命令行指定在可配置圖形中顯示什么。該工具依然很粗糙,對(duì)于用戶也不夠友好,不過毋庸置疑它對(duì)jrockit的終端用戶非常有用,所以這是一個(gè)非常不錯(cuò)但是不能通用的工具。
code coverage(試驗(yàn)性)
很多開發(fā)人員在以某種方式使用他們的應(yīng)用程序時(shí),使用code coverage分析來研究諸如代碼庫中的多少以及哪些部分正在運(yùn)行之類的狀況。測(cè)試人員喜歡使用code coverage來度量測(cè)試套件覆蓋應(yīng)用程序的比例。但是,對(duì)于大型應(yīng)用程序,由code coverage工具所引起的性能開銷通常是被禁止的。
jrockit內(nèi)置了高性能的行code coverage。當(dāng)啟用code coverage運(yùn)行時(shí),代碼將由記錄行命中的捕獲器生成。一旦某行被命中并記錄,就刪除捕獲器,jrockit可以繼續(xù)以接近全速的速度運(yùn)行。
要使jrockit記錄code coverage數(shù)據(jù),必須指定一個(gè)命令行選項(xiàng)。
用法 -xcodecoverage可以使用以下系統(tǒng)屬性來控制該行為:
系統(tǒng)屬性描述jrockit.codecoverage.filter=<filterspec>filterspec是個(gè)以分號(hào)(windows)或冒號(hào)(linux)隔開的篩選器字符串列表,它定義哪些類應(yīng)當(dāng)被覆蓋。以“-”開頭的篩選器字符串會(huì)被視為不應(yīng)當(dāng)覆蓋的類。
示例:
-djrockit.codecoverage.filter=
java/util/hashtable;com/bea/*;-com/bea/bla.*
<filename>設(shè)置包含篩選器定義的文件的文件名。文件格式為每行一個(gè)篩選器字符串。jrockit.codecoverage.outputfile=
<filename>設(shè)置存放輸出的文件。如果寫入<filename>_0,輸出文件不能被打開,那么將嘗試<filename>_1,以此類推。在多個(gè)jvm共享一個(gè)公共命令行的情況中,這可能會(huì)很有用。jrockit.codecoverage.testid=
<id-string>設(shè)置初始測(cè)試標(biāo)識(shí)符。jrockit.codecoverage.verbose使code coverage更為詳細(xì)。適用于在覆蓋文件(均是純文本文件)中執(zhí)行文本比較。jrockit.codecoverage.appendoutput設(shè)置對(duì)輸出文件的寫入為追加而不是覆蓋。
這里給出特定于code coverage的參數(shù),用于生成如下圖中所示的數(shù)據(jù)。
-xcodecoverage -djrockit.codecoverage.filter=com/jrockit/console/*;com/jrockit/common/* -djrockit.codecoverage.outputfile=console_coverage.txt在內(nèi)部,由一個(gè)code coverage小工具來解釋jrockit所生成的數(shù)據(jù),如圖3所示。
圖3:code coverage工具的輸出示例(點(diǎn)擊圖片查看大圖)
結(jié)束語
bea對(duì)java運(yùn)行時(shí)的掌控將其置于一個(gè)獨(dú)一無二的位置:bea交付了一些針對(duì)java平臺(tái)的低開銷的管理和監(jiān)控特性。很多針對(duì)bea jrockit的有趣的管理和使用特性正在開發(fā)中。其中一些已經(jīng)隨著包含在jrockit 5.0 r26中的jrockit mission control而可以使用,更多特性也即將出現(xiàn)。更多信息請(qǐng)參見mission control home page。
參考資料
an introduction to jrockit mission control,marcus hirt撰寫(dev2dev,2005年12月) memory leaks, be gone,staffan larsen撰寫(dev2dev,2005年6月)——提供了關(guān)于內(nèi)存泄漏檢測(cè)系統(tǒng)的大量信息 new features and tools in jrockit 5.0,eva andreasson撰寫(dev2dev,2005年2月) ——提供了一份很早但卻很有用的、jrockit 5.0中的多個(gè)特性的匯總 dev2dev jrockit product center——包含大量可以訂閱的信息和博客 mission control section,dev2dev——包含jrockit工具的更多信息