闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾剧懓顪冪€n亝鎹i柣顓炴閵嗘帒顫濋敐鍛婵°倗濮烽崑鐐烘偋閻樻眹鈧線寮撮姀鐘栄囨煕鐏炲墽鐓瑙勬礀閳规垿顢欑紒鎾剁窗闂佸憡顭嗛崘锝嗙€洪悗骞垮劚濞茬娀宕戦幘鑸靛枂闁告洦鍓涢ˇ顓熺節閳封偓閸曞灚鐤佸Δ鐘靛仜濡繂顕i鈧畷鐓庮熆椤忎焦娅婇柟顔筋殜閺佹劖鎯斿┑鍫濆毈闁诲海鎳撻幉锛勬崲閸曨厽顫曢柟鐑樻尰缂嶅洭鏌曟繛鍨姢闁荤喆鍔岄—鍐Χ鎼粹€茬凹缂備緡鍠楅幐鎼佹偩閻戣棄纭€闁绘劕绉堕崰鏍箖濞嗘挸绠f繝闈涙搐椤︹晠姊洪幎鑺ユ暠闁搞劌婀卞Σ鎰板箻鐎涙ê顎撴繝娈垮枟閸╁牊绂嶅┑瀣疄闁靛ň鏅涢悙濠囨煏婵炲灝鈧绮诲顒夋富闁靛牆妫涙晶顒勬煟閺冩垵澧撮柣鎿冨墴椤㈡宕掑Δ鈧禍楣冩偡濞嗗繐顏痪鐐倐閺屾稒鎯旈敐鍡樻瘓閻庢鍣崑濠囩嵁濡偐纾兼俊顖滅帛椤忕喖姊绘担鑺ョ《闁革綇绠撻獮蹇涙晸閿燂拷婵犵數濮烽弫鍛婃叏閻戣棄鏋侀柛娑橈攻閸欏繘鏌i幋锝嗩棄闁哄绶氶弻鐔兼⒒鐎靛壊妲紒鐐劤椤兘寮婚敐澶婄疀妞ゆ帊鐒﹂崕鎾剁磽娴e搫小闁告濞婂濠氭偄閸忓皷鎷婚柣搴ㄦ涧婢瑰﹤危椤斿墽纾藉ù锝呮惈鍟搁梺鍝ュУ閻楃姴顕f繝姘╅柍鍝勫€告禍婊堟⒑閸涘﹦绠撻悗姘嚇婵偓闁靛牆妫涢崢閬嶆⒑闂堟胆褰掑磿闁秴鐒垫い鎺嗗亾婵犫偓闁秴绠查柕蹇曞Л濡插牓鏌曡箛鏇炐㈤柤鏉跨仢閳规垿鍩ラ崱妤冧淮濡炪倖娉﹂崶顭戞閻庡箍鍎遍ˇ浼村煕閹寸姷纾奸悗锝庡亽閸庛儵鏌涙惔銏犲缂佽鲸甯為幏鐘诲箵閹烘挻顔掑┑鐘殿暜缁辨洟寮拠鑼殾闁绘梻鈷堥弫宥嗘叏濡じ鍚柡澶嬫倐濮婄粯鎷呴崫銉︾€┑鈩冦仠閸斿酣骞忕€n喖钃熼柕澶堝劤閿涙盯姊虹憴鍕妞ゆ泦鍥х闁逞屽墴閹嘲饪伴崘鐐枅閻庢鍠楅幃鍌氼嚕椤曗偓瀹曞ジ鎮㈤崫鍕辈闂傚倷鑳剁划顖毭洪弽顓炵9闁革富鍘搁崑鎾愁潩閻愵剙顏�
开发学院软件开发Java 剖析java.util.concurrent锁 阅读

剖析java.util.concurrent锁

 2010-10-09 08:12:23 来源:WEB开发网 闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾剧懓顪冪€n亜顒㈡い鎰Г閹便劌顫滈崱妤€骞婄紓鍌氬€瑰銊╁箟缁嬫鍚嬮柛顐線缂冩洟姊婚崒娆戭槮婵犫偓闁秵鎯為幖娣妼缁愭鏌″搴′簽濞戞挸绉甸妵鍕冀椤愵澀娌梺缁樻尪閸庣敻寮婚敐澶婂嵆闁绘劖绁撮崑鎾诲捶椤撴稑浜炬慨妯煎亾鐎氾拷闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾剧懓顪冪€n亝鎹i柣顓炴閵嗘帒顫濋敐鍛婵°倗濮烽崑娑⑺囬悽绋挎瀬闁瑰墽绮崑鎰版煙缂佹ê绗ч柍褜鍓﹂崣鍐潖閸濆嫅褔宕惰娴犲ジ姊虹拠鑼闁煎綊绠栭幃楣冩倻閽樺鎽曢梺闈涱檧婵″洭宕㈤悽鍛娾拺閻熸瑥瀚烽崯蹇涙煕閻樺磭澧甸柕鍡楀€圭缓浠嬪川婵犲嫬骞堥梺纭呭閹活亞妲愰弴鐔哄ⅰ闂傚倷绶氬ḿ褍煤閵堝洠鍋撳顐㈠祮闁绘侗鍣i獮鎺懳旈埀顒傜不閿濆棛绡€闂傚牊绋戦弳娆徝瑰⿰鍫㈢暫闁哄矉缍佹慨鈧柍鎯版硾濠€杈ㄧ珶閺囩喓绡€婵﹩鍘鹃崢鐢告⒑缂佹ê濮﹂柛鎾村哺閹ɑ娼忛妸銈囩畾闂佸湱绮敮鐐存櫠濞戞氨纾肩紓浣贯缚濞插鈧娲栧畷顒冪亙闂佸憡鍔曢崯鐘诲礈濠靛牊宕叉繛鎴炨缚閺嗗棗鈹戦悩杈厡闁轰焦鐗滅槐鎾存媴娴犲鎽甸梺鍦嚀濞层倝鎮鹃悜钘夌闁规惌鍘介崓鐢告⒑閻熸澘鎮侀柣鎺炵畵閹骞栨担鍏夋嫽婵炶揪绲块崕銈夊吹閳ь剟姊洪幖鐐测偓鏍偋閻樿崵宓侀煫鍥ㄧ⊕閺呮悂鏌ㄩ悤鍌涘濠电姷鏁告慨鐑藉极閸涘﹥鍙忛柣鎴f閺嬩線鏌涘☉姗堟敾闁告瑥绻戦妵鍕箻閸楃偟浠肩紓浣哄閸ㄥ爼寮诲☉銏犵疀闂傚牊绋掗悘鍫ユ倵閻熺増鍟炵紒璇插暣婵$敻宕熼姘鳖啋闁诲酣娼ч幗婊堟偩婵傚憡鈷戠痪顓炴媼濞兼劖绻涢懠顒€鏋庢い顐㈢箳缁辨帒螣閼测晜鍤岄梻渚€鈧偛鑻晶顔肩暆閿濆牆鍔垫い锔界叀閹繝濡舵径瀣帾闂佸壊鍋呯换鍐磻椤忓懐绠剧€瑰壊鍠曠花濠氬箚閻斿吋鈷戦悗鍦У閵嗗啴鏌ら崘鑼煟鐎规洘绻堥弫鍐焵椤掑嫧鈧棃宕橀鍢壯囨煕閳╁喚娈橀柣鐔稿姍濮婃椽鎮℃惔鈩冩瘣闂佺粯鐗曢妶绋跨暦閻戞ḿ绡€闁搞儜鍐ㄧギ闂備線娼ф蹇曟閺囥垹鍌ㄦい蹇撶墛閳锋垿鏌熼懖鈺佷粶闁告梹顨婇弻锟犲川椤旈敮濮囩紓浣稿€圭敮鐔妓囩€靛摜纾奸弶鍫涘妼缁楁碍绻涢悡搴g闁糕斁鍓濋幏鍛存煥鐎e灚缍楅梻鍌氬€峰ù鍥ь浖閵娾晜鍊块柨鏇炲€哥粻鏌ユ煕閵夘喖澧柡瀣╃窔閺岀喖宕滆鐢盯鏌¢崨顔藉€愰柡灞诲姂閹倝宕掑☉姗嗕紦闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾剧懓顪冪€n亜顒㈡い鎰Г閹便劌顫滈崱妤€骞婄紓鍌氬€瑰銊╁箟缁嬫鍚嬮柛顐線缂冩洟姊婚崒娆戭槮婵犫偓闁秵鎯為幖娣妼缁愭鏌″搴′簽濞戞挸绉甸妵鍕冀椤愵澀娌梺缁樻尪閸庣敻寮婚敐澶婂嵆闁绘劖绁撮崑鎾诲捶椤撴稑浜炬慨妯煎亾鐎氾拷  闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌i幋锝呅撻柛銈呭閺屻倝宕妷锔芥瘎婵炲濮靛銊ф閹捐纾兼繛鍡樺笒閸橈紕绱撴笟鍥ф珮闁搞劌鐖兼俊鎾礃椤旂厧绐涢梺鍝勵槹閸ㄥ綊宕㈠ú顏呭€垫鐐茬仢閸旀碍銇勯敂璇茬仸鐎规洩绻濋獮搴ㄦ嚍閵壯冨妇闂傚⿴鍋勫ú锕€煤閺嶃劎澧¢梻鍌欐祰椤曆呪偓鍨浮瀹曟粓鎮㈡總澶嬬稁闂佹儳绻愬﹢杈╁閸忛棿绻嗘い鏍ㄧ閹牊銇勯銏⑿㈡い顏勫暣婵″爼宕卞Δ鈧~搴ㄦ⒑閸涘⿴鐒奸柛銉戝懎寮ㄥ┑鐘灱濞夋稖鐧岄梺缁樻煥閸氬鎮¢妷鈺傚€甸柨婵嗛閸樻挳鏌涚€n偅灏扮紒缁樼箓椤繈顢樺☉娆忣伖闂佽崵鍠愮划搴㈡櫠濡ゅ啯鏆滈柟鐑樻尵椤╂彃霉閻撳海鎽犻柣鎾存礋閺岀喖骞嗚閸ょ喖鏌嶉挊澶樻█闁哄苯绉剁槐鎺懳熼懡銈呭汲婵$偑鍊ら崑鍛崲閸儱绠犳繝濠傛噹閺嬪牊淇婇婵愬殭妞ゅ繐缍婂濠氬磼濞嗘埈妲梺纭咁嚋缁辨洜鍒掑▎鎾崇闁挎柨鎼禍濂告⒑閸濆嫷妲归柛銊у枛瀵悂寮崼鐔哄幐闂佸憡鍔х徊鑺ョ閸撗呯=濞达綀娅g敮娑氱磼鐎n偅灏扮紒鍌涘浮閺佸啴宕掑鎲嬬床婵犳鍠楅敃鈺呭礈閿曞倹鍊甸柟鎯板Г閳锋帒霉閿濆懏鎲搁柨娑樼Ф缁辨帡顢氶崨顓犱桓濡ょ姷鍋為崹鍨暦閸洦鏁嗛柛灞炬皑閵堬箓姊虹拠鎻掑毐缂傚秴妫欑粋宥夊冀椤撶偟鍝楁繛瀵稿Т椤戝棝鎮″▎鎾粹拺妞ゆ挶鍔庨悾鍗烆熆瑜滈崹閬嶅Φ閸曨垰妫橀柛顭戝枓閸嬫挾鎲撮崟顓涙敵婵犵數濮村ú锕傚磹闁垮浜滈煫鍥ㄦ尭椤忋倝鏌涚€n偅宕岀€殿喖鈧噥妾ㄥ┑鐐插悑閻楁洟鍩為幋锔藉亹閻庡湱濮撮ˉ婵嬫⒑缁嬭儻顫﹂柛鏂块叄楠炲顫㈠畝鈧悿鈧┑鐐村灦宀e潡鎮块崨瀛樷拺闁革富鍙€濡炬悂鏌涢悩鎰佹疁鐎殿喗鐓¢獮鏍ㄦ媴閸︻厼寮抽梻浣虹帛濞叉牠宕愰崷顓涘亾濮樼偓瀚�
核心提示:1. 导言程序的性能分析是应用程序开发过程中的一个重要方面,这个工作一般是由一些专业人员来完成的,剖析java.util.concurrent锁,他们的目标是在一个特定的平台上,提高代码的性能,更多的并行/多线程Java程序将不断涌现,我们需要更好的工具去剖析这些并行程序,当程序是运行在多核平台的多线程或者并行程序的时

1. 导言

程序的性能分析是应用程序开发过程中的一个重要方面。这个工作一般是由一些专业人员来完成的,他们的目标是在一个特定的平台上,提高代码的性能。当程序是运行在多核平台的多线程或者并行程序的时候,提高性能这个问题就变得更加困难了。因为在这样的情况下,不仅需要考虑代码的性能,还需要考虑代码的可伸缩性。

随着Java 5中引入了java.util.concurrent (JUC)包,在Java语言中出现了一种新的锁。JUC包使用得越来越普遍,因为更多的应用程序需要为了多核系统而开发或仔细地调优。虽然JLM可以找到传统的Java锁的详细的竞争信息,但是却没有同样的工具能够找到java.util.concurrent.locks包的锁竞争信息。 Sun/Oracle、IBM,还有其他Java厂商也都没有这样的工具。缺乏对JUC锁的剖析工具正是我们开发这个锁工具,jucprofiler(Multicore SDK的一部分)的动机。

2. jucprofiler概览

当在程序中使用JUC锁的时候,线程会在下面两种情况下“停止”执行:

当线程A试图去获得一个JUC锁,但这个锁却已经被另外一个线程获得,那么线程A不得不“停止”,直到这个锁被释放或者超时。

当线程A调用了java.util.concurrent.locks.Condition的任意一个“等待”的API,线程A会停止执行,直到另外一个线程通知它或者超时。

我们分别把这两种情况称作“锁竞争时间”和“等待时间”。

jucprofiler就是为了捕获以上两种情况的时间开销而设计和实现的。

2.1. 代码修改(Instruments)

为了获取JUC锁的运行时数据,需要提前修改一些JUC类,然后替换掉JRE中相应的类。在首次使用jucprofiler之前,用户需要运行命令去生成PreInstrument.jar。假设JRE没有改变的话,这个步骤只需要做一次。(如果用户改变了JRE,那么用户需要自己删除 PreInstrument.jar,然后重新运行这个命令,来再次生成PreInstrument.jar)。

剖析java.util.concurrent锁

2.1.1. 锁竞争时间开销

对于锁竞争时间开销,jucprofiler记录了申请类 java.util.concurrent.locks.AbstractQueuedSynchronizer 和类java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject的实例,并且给这些实例分配唯一的标识。

方法

调用位置

java.util.concurrent.locks.LockSupport

park (Object);

类AbstractQueuedSynchronizer中的方法parkAndCheckInterrupt()

 

parkNanos(Object blocker, long nanos)

类AbstractQueuedSynchronizer中的方法doAcquireNanos(int arg, long nanosTimeout)与doAcquireSharedNanos(int arg, long nanosTimeout)

2.1.2. 锁等待时间开销

对于锁等待时间开销,jucprofiler获取了在不同的位置调用类java.util.concurrent.locks.LockSupport的方法park(blocker)与parkNanos(blocker, nanos)的时间开销:

方法

调用位置

java.util.concurrent.locks.LockSupport

park (Object);

类 AbstractQueuedSynchronizer除parkAndCheckInterrupt()以外的方法

 

parkNanos(Object blocker, long nanos)

类AbstractQueuedSynchronizer除doAcquireNanos(int arg, long nanosTimeout)与doAcquireSharedNanos(int arg, long nanosTimeout) 以外的方法

3. 如何使用

本节将通过一个真实的应用来探究如何使用jucprofiler来寻找程序中的问题。

3.1. 运行jucprofiler

使用如下的命令:

$ java -Xbootclasspath/p:$JUCP/BCIRuntime.jar:$JUCP/PreInstrument.jar 
 -javaagent:$JUCP/BCIAgent.jar=callStackDepth=10:allocationStackDepth=0 
:,msdk.idp=com.ibm.msdk.bciagent.JUCInstrumentDecisionProvider,:libPath=$JUCP:traceJUC=on 
 -cp .:derby.jar JavaDBDemo 

jucprofiler可以用于任何运行在JDK6上的Java程序上。假设jucprofiler安装在了目录$JUCP中,在 jucprofiler运行完你的程序之后,就会生成一个叫"BCIAgent.***.bci.trace"的文件,其中"***"代表本次运行的唯一时间戳。

3.2. 获取结果

运行如下所示的命令来得到结果:

$ java -Xmx1000m -jar $JUCP/BCITraceReader.jar {tracefile} {resultOutputFile} 

其中:

{tracefile}是一个追踪文件的全路径名称或者是一个包含若干追踪文件的目录名称,比如BCIAgent.***.bci.trace。

{resultOutputFile}是可选的参数,用来指定存放分析结果的文件。如果没有这个选现,那么分析结果就会在控制台打印出来。

说明:因为对追踪文件事后分析过程会有一些内存开销,所以最好用Java选项-Xmx来增加堆的大小。在我们的实验里,分析160M的文件,需要800M的内存。

3.3. 结果解析

如下图所示,纯文本输出包含了不同类型的信息,比如锁的名称,锁竞争的次数和时间,锁被持有的时间和次数,锁在申请时线程的调用栈,持续的时间和每一次锁竞争的调用栈。这些结果有助于用户发现JUC锁竞争造成的程序瓶颈。

在“LEGEND” 段之前,结果报告首先,按照锁竞争次数和时间的降序,总结了程序中全部的JUC锁竞争。其中每一行属于两种类型的一种,“AQS”代表JUC 锁,“CHM”代表ConcurrentHashMap.  因为一个ConcurrentHashMap内部被分割为了若干个片段(segment)进行存储,而且每一个片段都被一个不同的JUC锁保护,所以,从锁的角度来看,ConcurrentHashMap可以被看作为一个JUC锁的集合。例如,“CHM@8”有276次锁竞争,一共3,945,7000 纳秒的竞争时间,这就是说,“CHM@8”中的所有片段的JUC锁共有276次锁竞争,一共3,945,7000纳秒的竞争时间。这样的对锁的分组能够帮助程序员发现哪一个ConcurrentHashMap对象发生了最严重的锁竞争。相反,JUC锁“AQS@1790” 不属于任何一个ConcurrentHashMap对象,它就是程序中一个显式使用的锁。

说明:因为在这个例子中,没有打开记录获得锁的功能,所以列HOLD-COUNT和HOLD-TIME都是零。

在“LEGEND”段之后,结果给出了每一个JUC锁竞争的详细信息。在下边的结果片段中,对于ConcurrentHashMap “CHM@8” ,锁竞争出现在两个用来保护片段的锁上 “Lock [AQS@135]” and “Lock [AQS@146]”。对于“Lock [AQS@135]”,它在一个程序位置出现竞争,显示了竞争的次数,时间和竞争时刻的线程调用栈。对于“Lock [AQS@146]”,给出了同样的信息。这些细节信息可以很好地帮助程序员来定位程序中的锁竞争,并且清楚地理解ConcurrentHashMap中哪个片段竞争最严重。

Multicore Software Development Toolkit Version_2.1 
 
j.u.c Lock Profiler Report 
 
        NAME  CONTD-COUNT     CONTD-TIME   HOLD-COUNT      HOLD-TIME 
        CHM@8      276      39457000       0          0 
      AQS@1790       36       4029000       0          0 
       AQS@131       17       630000       0          0 
================================================================================================= 
 LEGEND: 
        NAME : Name of juc lock(AQS) or ConcurrentHashMap(CHM), format: <Type>@<Idgt; 
     CONTD-COUNT : Total count of lock contention 
     CONTD-TIME : Total time of lock contention in nanosecond 
     HOLD-COUNT : Total count of lock hold 
      HOLD-TIME : Total time of lock hold in nanosecond 
================================================================================================== 
 
ConcurrentHashMap [CHM@8]: 
 
----------------------------------------------------------------------------------------------------------- 
Lock [AQS@135]: 
 
----------------------------------------------------------------------------------------------------------- 
Lock Contention 1 
CONTD-COUNT: 25 
CONTD-TIME: 10827000 
Call Stack: 
java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:758) 
java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:789) 
java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1125) 
java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:197) 
java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:273) 
java.util.concurrent.ConcurrentHashMap$Segment.remove(ConcurrentHashMap.java:530) 
java.util.concurrent.ConcurrentHashMap.remove(ConcurrentHashMap.java:934) 
org.apache.derby.impl.services.locks.ConcurrentLockSet.unlock(ConcurrentLockSet.java:740) 
org.apache.derby.impl.services.locks.ConcurrentLockSet.unlockReference(ConcurrentLockSet.java:784) 
org.apache.derby.impl.services.locks.LockSpace.unlockReference(LockSpace.java:275) 
 
 
Lock [AQS@146]: 
 
----------------------------------------------------------------------------------------------------------- 
Lock Contention 1 
CONTD-COUNT: 22 
CONTD-TIME: 2009000 
Call Stack: 
java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:758) 
java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:789) 
java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1125) 
java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:197) 
java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:273) 
java.util.concurrent.ConcurrentHashMap$Segment.remove(ConcurrentHashMap.java:530) 
java.util.concurrent.ConcurrentHashMap.remove(ConcurrentHashMap.java:934) 
org.apache.derby.impl.services.locks.ConcurrentLockSet.unlock(ConcurrentLockSet.java:740) 
org.apache.derby.impl.services.locks.ConcurrentLockSet.unlockReference(ConcurrentLockSet.java:784) 
org.apache.derby.impl.services.locks.LockSpace.unlockReference(LockSpace.java:275) 

3.4. 在可视化分析器中打开追踪文件

可视化分析器,作为multicore SDK的一部分,提供了一些Eclipse视图,可以用表格和图表来显示jucprofiler文件。当前有两个视图,一个叫“J.U.C 统计”视图,另外一个叫“J.U.C 同步”视图。

“J.U.C 统计”视图如下所示。右边的两列是“竞争时间”和“竞争次数”。“申请栈”是关于JUC锁在申请的时候的调用位置。

剖析java.util.concurrent锁

查看原图(大图)

“J.U.C 同步”视图如下所示。第一列是时间,表明什么时候锁出现了竞争。第二列是线程,表明锁竞争发生哪个线程。第三列是锁,表明那个JUC锁出现竞争了。最后一列是方法,表明锁竞争是在什么位置发生的。

剖析java.util.concurrent锁

3.5. 在线控制

在执行的过程中,jucprofiler会创建一个“控制服务器”监听2009端口。用户可以使用“控制客户端”连接这个端口,控制jucprofiler的行为,比如,可以动态打开或者关闭追踪功能:

$ java -cp BCIRuntime.jar 

com.ibm.msdk.bciruntime.control.ControlClient HOST -m [b|i] –b 

START -e END

其中:

HOST:“控制客户端”要去连接的主机名称,缺省是本机。

-m [b|i]: “控制客户端”执行的模式。- b是批处理模式、- i是交互模式。缺省是交互模式。

-b START:如果是批处理模式,START是开始剖析的时间。

-e END:END是剖析过程的持续时间。

3.5.1. 交互模式

有一个简单的shell,用户可以输入一些命令juc.on和juc.off来打开和关闭jucprofiler。比如,java -cp BCIRuntime.jar com.ibm.msdk.bciruntime.control.ControlClient, “控制客户端” 会连接到本机, 并且打开一个shell来控制jucprofiler.

$ java -cp BCIRuntime.jar com.ibm.msdk.bciruntime.control.ControlClient 
jucprofiler control> juc.on 
juc.on 
jucprofiler t control> start 
start 
jucprofiler control> stop 
stop 
jucprofiler control> juc.off 
juc.off 
jmit control> quit 
quit

$ java -cp BCIRuntime.jar com.ibm.msdk.bciruntime.control.ControlClient localhost -m b -b 2 -e 10 
Start tracing in 2 seconds 
Start tracing 
Stop tracing in 10 seconds 
Stop tracing 
quit

3.5.2. 批处理模式

jucprofiler也支持批处理模式。比如, java -cp BCIRuntime.jar com.ibm.msdk.bciruntime.control.ControlClient mtrat-test.dyndns.org -m b -b 10 -e 10, 意思是 “控制客户端”会连接到机器mtrat-test.dyndns.org,10秒后启动jucprofiler,然后10秒后停止 jucprofiler。

4. 结论

随着多核处理器成为主流,更多的并行/多线程Java程序将不断涌现。我们需要更好的工具去剖析这些并行程序。本文介绍的jucprofiler填补了Java性能分析工具中的一个重要缺口。

Tags:剖析 java util

编辑录入:爽爽 [复制链接] [打 印]
[]
  • 好
  • 好的评价 如果觉得好,就请您
      0%(0)
  • 差
  • 差的评价 如果觉得差,就请您
      0%(0)
更多精彩
    赞助商链接

    热点阅读
      焦点图片
        最新推荐
          精彩阅读