JVM運(yùn)行狀態(tài)監(jiān)控及分析_第1頁(yè)
JVM運(yùn)行狀態(tài)監(jiān)控及分析_第2頁(yè)
JVM運(yùn)行狀態(tài)監(jiān)控及分析_第3頁(yè)
JVM運(yùn)行狀態(tài)監(jiān)控及分析_第4頁(yè)
JVM運(yùn)行狀態(tài)監(jiān)控及分析_第5頁(yè)
已閱讀5頁(yè),還剩25頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

JVM運(yùn)行狀態(tài)監(jiān)控及分析TITLE技術(shù)方案技術(shù)方案簡(jiǎn)介目的背景應(yīng)用系統(tǒng)運(yùn)行時(shí)出現(xiàn)內(nèi)存溢出問(wèn)題,需要定位及解決。定義、首字母縮寫詞和縮略語(yǔ)暫無(wú)。參考資料本方案的參考資料如下:周志明,《深入理解Java虛擬機(jī):JVM高級(jí)特性與最佳實(shí)踐》MAT,/mat從轉(zhuǎn)儲(chǔ)(Dump)文件中調(diào)試并除錯(cuò),/question/129540%5f23220……約束本文描述的工具,只在JDK6以上版本中進(jìn)行驗(yàn)證。可能部分工具在JDK1.4.2_14和JDK1.5.0_06以上也能夠執(zhí)行,但并未實(shí)際測(cè)試驗(yàn)證,僅供參考。常見(jiàn)JVM內(nèi)存相關(guān)問(wèn)題現(xiàn)象通常內(nèi)存溢出時(shí)JVM會(huì)提示具體的內(nèi)存溢出原因,下面是幾種常見(jiàn)的情況及簡(jiǎn)要的原因說(shuō)明及相關(guān)的JVM配置。棧溢出:StackOverflowErrorJVM輸出信息:“java.lang.StackOverflowError”。JVM相關(guān)機(jī)制:JVM在執(zhí)行Java方法調(diào)用時(shí)需要使用棧傳遞調(diào)用參數(shù)、返回值以及保存局部變量表,通常組織為棧幀(StackFrame)結(jié)構(gòu)。從概念上說(shuō),每次Java方法調(diào)用都會(huì)消耗一定的棧內(nèi)存,當(dāng)這個(gè)方法調(diào)用結(jié)束返回后釋放這部分內(nèi)存。而每個(gè)Java線程對(duì)應(yīng)的棧內(nèi)存是有限的(通常JVM啟動(dòng)后就固定了),因此當(dāng)方法嵌套層數(shù)過(guò)多或者棧幀內(nèi)的數(shù)據(jù)結(jié)構(gòu)(如局部變量表)過(guò)大時(shí),可能出現(xiàn)StackOverflowError。JVM控制參數(shù):可以通過(guò)-Xss1024K設(shè)置線程棧大小為1024K。通常無(wú)需設(shè)置此參數(shù),在不同OS下的JVM均有自己的默認(rèn)值設(shè)置,一般在256K-1024K之間。常見(jiàn)原因分析建議:出現(xiàn)此問(wèn)題通常應(yīng)該先分析應(yīng)用系統(tǒng)的原因,而不是考慮增大“-Xss”參數(shù)設(shè)置值。因?yàn)槌霈F(xiàn)此問(wèn)題的最可能原因是過(guò)深的方法調(diào)用(比如錯(cuò)誤的遞歸調(diào)用造成方法調(diào)用層次過(guò)深),即應(yīng)用程序中的編程錯(cuò)誤造成棧溢出。當(dāng)出現(xiàn)StackOverflowError時(shí),根據(jù)此異常的詳細(xì)信息通??梢员容^明確地找到錯(cuò)誤代碼的可能位置,通常不需要復(fù)雜的工具支持。堆溢出JVM輸出信息:“java.lang.OutOfMemoryError:Javaheapspace”,或者類似輸出信息,視JVM廠商及版本略有區(qū)別,但關(guān)鍵字都是“heap”或者“堆”。JVM相關(guān)機(jī)制:從概念上說(shuō),Heap是存儲(chǔ)Java類實(shí)例和數(shù)組的內(nèi)存區(qū)。比如任何“obj=newXClass();”的調(diào)用都是在Heap中進(jìn)行內(nèi)存分配,當(dāng)不能成功進(jìn)行這種內(nèi)存分配時(shí),JVM將拋出“java.lang.OutOfMemoryError:Javaheapspace”。JVM控制參數(shù):-Xms512m:設(shè)置Heap最小值為512m;-Xmx1024m:設(shè)置Heap最大值為1024m;JVM控制參數(shù)設(shè)置相關(guān)知識(shí)及建議:在生產(chǎn)環(huán)境中可以將-Xms和-Xmx設(shè)為相同大小,避免JVM動(dòng)態(tài)調(diào)整Heap大小;在32位系統(tǒng)上(無(wú)論是Windows還是Unix/Linux),-Xmx參數(shù)通常無(wú)法設(shè)置到大于1500m,且此值在不同的系統(tǒng)上并不相同;在32位系統(tǒng)上,并不建議將-Xmx設(shè)到最大(如1500m)。因?yàn)?2位系統(tǒng)中JVM進(jìn)程的可用的內(nèi)存是有限的(一個(gè)32為系統(tǒng)上的進(jìn)程的地址空間最大為4G,能使用的內(nèi)存最大為4G,實(shí)際上OS核心會(huì)占據(jù)1~2G地址空間,而留給應(yīng)用層的地址空間通常不超過(guò)3G,應(yīng)用層真正能夠使用的通常在2G以內(nèi)),這些內(nèi)存除了JavaHeap使用,JVM進(jìn)程本身、NativeThread都需要使用。因此過(guò)大的JavaHeap可能增大其他溢出的可能;常見(jiàn)原因分析建議:Java堆內(nèi)存溢出是較為常見(jiàn)的情況,有可能是因?yàn)椋簯?yīng)用系統(tǒng)的錯(cuò)誤導(dǎo)致的問(wèn)題,即應(yīng)用系統(tǒng)錯(cuò)誤地生成了太多的新Object,JVM中用來(lái)存儲(chǔ)對(duì)象的堆(heap)中無(wú)法容納新Object。此時(shí)需要通過(guò)分析HeapDump(堆轉(zhuǎn)儲(chǔ)文件)定位并修正問(wèn)題;也有可能并非程序錯(cuò)誤,而是業(yè)務(wù)場(chǎng)景或者并發(fā)程度確實(shí)需要更大的Heap來(lái)支持。此時(shí)有多種可能的解決方案:分析HeapDump(堆轉(zhuǎn)儲(chǔ)文件),確定應(yīng)用中內(nèi)存使用情況,更改應(yīng)用的實(shí)現(xiàn)邏輯,減少新Object的創(chuàng)建。其本質(zhì)是以時(shí)間換空間的策略,即增加應(yīng)用邏輯執(zhí)行時(shí)間,來(lái)?yè)Q取更少的內(nèi)存需求;增大Heap,即設(shè)置更大的-Xmx參數(shù)。32位系統(tǒng)上余地并不大,并可能增大Thread相關(guān)內(nèi)存溢出的可能性;更換為使用64位系統(tǒng),64位系統(tǒng)才能支持更大的Heap,但增大Heap帶來(lái)的不僅是好處,也可能造成GC時(shí)間增加,應(yīng)用系統(tǒng)“停頓”的感覺(jué)更明顯;堆內(nèi)存溢出較為常見(jiàn),準(zhǔn)確地定位及分析需要借助工具,后文將詳細(xì)描述如何借助工具進(jìn)行分析。持久區(qū)(方法區(qū))溢出JVM輸出信息:“java.lang.OutOfMemoryError:PermGenspace”。JVM相關(guān)機(jī)制:概念上說(shuō),JVM持久區(qū)(方法區(qū))是用來(lái)存儲(chǔ)類型相關(guān)的信息,如該類型的常量池,字段或方法信息,而且類型中的類(靜態(tài))變量同樣也是存儲(chǔ)在方法區(qū)中(如到ClassLoader的引用和到Class類的引用)。當(dāng)持久區(qū)不足以容納需要加載的Class時(shí)JVM將拋出此異常,異常中明確指出是持久區(qū)內(nèi)存不足。JVM控制參數(shù):-XX:PermSize=64m:設(shè)置初始持久區(qū)大小為64m;-XX:MaxPermSize=256m:設(shè)置持久區(qū)最大為256m;常見(jiàn)原因分析建議:此問(wèn)題通常是太多的Class需要加載造成的,Class的數(shù)量和應(yīng)用系統(tǒng)的代碼規(guī)模相關(guān),較大的應(yīng)用系統(tǒng)需要較大的MaxPermSize設(shè)置。需要注意的是,JavaEE應(yīng)用中的jsp最終會(huì)被編譯成Class并加載,因此可能在大量使用jsp的JavaEE應(yīng)用系統(tǒng)中需要設(shè)置較大的MaxPermSize,但通常不應(yīng)該超過(guò)256m。另外,對(duì)于使用了ASM/CGLib等字節(jié)碼工具動(dòng)態(tài)生成Class的系統(tǒng),編程錯(cuò)誤導(dǎo)致的運(yùn)行時(shí)大量生成Class也可能導(dǎo)致此異常。此異常明確地說(shuō)明了問(wèn)題,且除了編程錯(cuò)誤一般都能夠通過(guò)加大MaxPermSize參數(shù)值來(lái)解決,通常不需要復(fù)雜的工具進(jìn)行分析定位。無(wú)法創(chuàng)建OS本地線程JVM輸出信息:“java.lang.OutOfMemoryError:unabletocreatenewnativethread”。JVM相關(guān)機(jī)制:概念上說(shuō),JVM中啟動(dòng)一個(gè)Thread,通常會(huì)在OS中創(chuàng)建并啟動(dòng)一個(gè)本地線程(NativeThread),而無(wú)論是因?yàn)閮?nèi)存問(wèn)題還是本地線程數(shù)量問(wèn)題,都有可能導(dǎo)致此異常。NativeThread內(nèi)存問(wèn)題:OS在創(chuàng)建本地線程時(shí)同樣需要使用內(nèi)存,但這個(gè)內(nèi)存不在JVM的堆內(nèi)存范圍內(nèi),而是在JVM進(jìn)程之內(nèi)、JavaHeap/方法區(qū)等內(nèi)存之外。因此完全有可能JavaHeap越大,剩余的用來(lái)創(chuàng)建NativeThread的內(nèi)存越小,從而可創(chuàng)建的NativeThread越少,出現(xiàn)此異常的可能性越大;NativeThread數(shù)量問(wèn)題:OS對(duì)于進(jìn)程允許創(chuàng)建的線程數(shù)量通常有限制,因此JVM能夠啟動(dòng)的Thread數(shù)量也有限,當(dāng)JVM中啟動(dòng)的Thread超出此限制時(shí)將出現(xiàn)此異常。通常JVM中已經(jīng)啟動(dòng)的Thread數(shù)量應(yīng)該是有限的,除非是程序錯(cuò)誤啟動(dòng)了大量的Thread。JVM控制參數(shù):無(wú),但通常減少-Xmx的值能夠保留更多的內(nèi)存給OS線程。常見(jiàn)原因分析建議:出現(xiàn)此問(wèn)題時(shí),只要獲取JVM當(dāng)時(shí)的ThreadDump(線程轉(zhuǎn)儲(chǔ)信息),并對(duì)ThreadDump進(jìn)行分析即可。分析ThreadDump信息很容易獲取JVM線程相關(guān)的信息,判斷JVM中是否存在預(yù)料之外的線程,或者線程所處的狀態(tài)和正在執(zhí)行的調(diào)用是否符合預(yù)期。內(nèi)存泄漏嚴(yán)格意義上來(lái)說(shuō),我們一般遇到的JVM中的內(nèi)存泄漏其實(shí)不是內(nèi)存泄漏,因?yàn)閲?yán)格地說(shuō)內(nèi)存泄漏指的是已經(jīng)分配的內(nèi)存無(wú)法被應(yīng)用系統(tǒng)正確回收。而我們通常說(shuō)的JVM中的內(nèi)存泄漏只是部分對(duì)象被其他對(duì)象持有引用,因此不能被GC過(guò)程回收;同時(shí),這些不能回收的對(duì)象被應(yīng)用系統(tǒng)“遺忘”了,不再有任何用處的同時(shí)還占據(jù)著大量?jī)?nèi)存。在應(yīng)用系統(tǒng)看來(lái)這部分內(nèi)存像是丟失了(或者泄露了)。我們解決內(nèi)存泄漏問(wèn)題就是要找到的是這些應(yīng)用程序中的錯(cuò)誤。舉個(gè)簡(jiǎn)單的例子:MapglobalMap=newHashMap<String,List<SomeObject>>();globalMap在整個(gè)應(yīng)用系統(tǒng)生命周期內(nèi)都會(huì)被引用,因此不能被GC回收。因而任何globalMap.put(aString,aList)的操作將在globalMap中引用aString和aList兩個(gè)對(duì)象,直到被明確清除出globalMap后aString和aList才有可能被GC回收,否則此兩個(gè)對(duì)象將永遠(yuǎn)占據(jù)JVM內(nèi)存。如果應(yīng)用系統(tǒng)是“忘了”從globalMap中remove(aString),則對(duì)應(yīng)用系統(tǒng)來(lái)說(shuō)就像是aString和aList所占的內(nèi)存“泄漏”了。JVM異常退出JVM運(yùn)行過(guò)程中有可能異常退出,即JVM進(jìn)程忽然消失,此時(shí)通常不是JavaStack或者JavaHeap出現(xiàn)異常,而是與OS本地堆棧有關(guān)。JVM中運(yùn)行的應(yīng)用系統(tǒng)通常難以處理此問(wèn)題,但如果應(yīng)用系統(tǒng)中使用了JNI,則有可能與此部分代碼相關(guān)。在Windows上,JVM異常退出時(shí)通常會(huì)生成“hs_err_pidXXXX.log”文件,此文件位于JVM進(jìn)程的“當(dāng)前路徑”下(如Tomcat的bin/),可以從此文件中得到異常退出時(shí)的現(xiàn)象。遺憾的是,應(yīng)用系統(tǒng)開(kāi)發(fā)人員很難分析此文件,但可以根據(jù)此文件得到一些信息,或者將此文件反饋給能夠分析的技術(shù)社區(qū)。下面列舉幾種HotSpotJVM異常退出時(shí)產(chǎn)生的“hs_err_pidXXXX.log”文件中的信息:#AnunexpectederrorhasbeendetectedbyJavaRuntimeEnvironment:#EXCEPTION#AnunexpectederrorhasbeendetectedbyJavaRuntimeEnvironment:#EXCEPTION_STACK_OVERFLOW(0xc00000fd)atpc=0x6da3a7fd,pid=3012,tid=3108#JavaVM:JavaHotSpot(TM)ClientVM(11.0-b15mixedmodewindows-x86)#Problematicframe:#V[jvm.dll+0x18a7fd]#Ifyouwouldliketosubmitabugreport,pleasevisit:#/webapps/bugreport/crash.jsp##AnunexpectederrorhasbeendetectedbyJavaRuntimeEnvironment:#AnunexpectederrorhasbeendetectedbyJavaRuntimeEnvironment:#java.lang.OutOfMemoryError:requested1024000bytesforGrETinC:\BUILD_AREA\jdk6_10\hotspot\src\share\vm\utilities\growableArray.cpp.Outofswapspace?#InternalError(allocation.inline.hpp:42),pid=4060,tid=3816#Error:GrETinC:\BUILD_AREA\jdk6_10\hotspot\src\share\vm\utilities\growableArray.cpp#JavaVM:JavaHotSpot(TM)ClientVM(11.0-b15mixedmodewindows-x86)#Ifyouwouldliketosubmitabugreport,pleasevisit:#/webapps/bugreport/crash.jsp注:上面列舉的JVM異常只包含部分總結(jié)性的信息,log文件中還有更多的詳細(xì)信息。HotSpotJVM之外的其他JVM是否有類似信息尚未確定,但此類問(wèn)題通常應(yīng)用層開(kāi)發(fā)者難以解決(JNI相關(guān)應(yīng)用的開(kāi)發(fā)者除外)。JVM運(yùn)行時(shí)信息收集ThreadDump/線程轉(zhuǎn)儲(chǔ)ThreadDump中包含下列信息:所有JVM中啟動(dòng)了但是未結(jié)束的Thread列表;每個(gè)Thread當(dāng)前所處的狀態(tài)及其調(diào)用棧(StackTrace);JVM內(nèi)部是否出現(xiàn)死鎖(Deadlock);基于ThreadDump信息可以確認(rèn)JVM當(dāng)前的執(zhí)行狀態(tài),ThreadDump信息常見(jiàn)的收集方法包括:使用jvisualvm:在所有平臺(tái)上,當(dāng)可以通過(guò)jvisualvm監(jiān)控JVM運(yùn)行時(shí),可以直接在jvisualvm中進(jìn)行ThreadDump,請(qǐng)參見(jiàn)jvisualvm的說(shuō)明;Windows平臺(tái):在JVMConsole(比如Tomcat啟動(dòng)時(shí)的后臺(tái)窗口)下按下組合鍵Ctrl-Break,Console中將打印ThreadDump信息。當(dāng)Console的緩沖區(qū)不夠大時(shí)可能無(wú)法顯示全部信息,需要增大Console的緩沖區(qū);Unix/Linux平臺(tái):先找到對(duì)應(yīng)的JVM進(jìn)程號(hào)(pid):ps–ef|grepjavakill-3(JVM進(jìn)程號(hào)):此時(shí)ThreadDump信息將輸出到JVMConsole中。此命令不會(huì)終止JVM運(yùn)行,只是輸出ThreadDump信息;JavaHeapDump/堆轉(zhuǎn)儲(chǔ)JVMHeapDump的方法與JVM密切相關(guān),因此后面的描述基于不同運(yùn)行環(huán)境的JVM分別描述。SUN/OracleHotSpotJava6+版本的SUN/OracleHotSpotJVM支持下列方式生成HeapDump:基于JVM事件:當(dāng)JVM運(yùn)行過(guò)程中出現(xiàn)OutOfMemoryError時(shí)自動(dòng)HeapDump,這也是生產(chǎn)系統(tǒng)中最可行的HeapDump生成方法。涉及參數(shù)包括:-XX:+HeapDumpOnOutOfMemoryError:當(dāng)內(nèi)存溢出時(shí)進(jìn)行HeapDump,默認(rèn)在Java進(jìn)程的“當(dāng)前目錄”下生成類似于“java_pid1340.hprof”形式的文件??梢杂?XX:HeapDumpPath控制生成文件的位置;-XX:HeapDumpPath=path:設(shè)置OutOfMemoryError時(shí)JVM生成HeapDump文件的位置。此參數(shù)默認(rèn)值為“./java_pid%p.hprof”,其中“%p”代表Java進(jìn)程的PID(ProcessID,進(jìn)程標(biāo)識(shí)),所以會(huì)在Java進(jìn)程的當(dāng)前目錄下生成包含PID的.hprof文件;交互式HeapDump:在JVM運(yùn)行中,以交互式方式獲取HeapDump,通常用于開(kāi)發(fā)調(diào)試階段定位問(wèn)題,生產(chǎn)環(huán)境還是建議基于JVM事件進(jìn)行HeapDump,方式包括:使用jvisualvm:在所有平臺(tái)上,當(dāng)可以通過(guò)jvisualvm監(jiān)控JVM運(yùn)行時(shí),可以直接在jvisualvm中進(jìn)行HeapDump,請(qǐng)參見(jiàn)jvisualvm的說(shuō)明;使用JDK中的jmap工具:jmap-dump[live,]format=b,file=filenamepid使用OS功能:在Linux中,使用“無(wú)害”的gcore命令或破壞性的“kill-6”或“kill-11”命令來(lái)生成一個(gè)內(nèi)核文件。然后,使用jmap從內(nèi)核文件中提取一個(gè)堆轉(zhuǎn)儲(chǔ)文件:jmap-dump:format=b,file=heap.hprofpath_to_java_executable_core;使用Ctrl+Break:如果運(yùn)行的應(yīng)用程序設(shè)置了-XX:+HeapDumpOnCtrlBreak命令行選項(xiàng),那么在通過(guò)控制臺(tái)發(fā)出Ctrl+Break事件或SIGQUIT(通常通過(guò)kill-3生成),那么會(huì)生成一個(gè)HPROF格式的轉(zhuǎn)儲(chǔ)文件和一個(gè)線程Dump。有一些版本不支持這個(gè)選項(xiàng),那么在遇到這些情況時(shí)可以嘗試使用:-Xrunhprof:format=b,file=heapdump.hprof。并不推薦使用這種方式,一些HotSpot版本不支持此參數(shù),建議使用上述其他交互式方式。IBMAIX+J9JVM此環(huán)境下可以通過(guò)下列方式獲取HeapDump:基于JVM事件:當(dāng)JVM運(yùn)行過(guò)程中出現(xiàn)OutOfMemoryError時(shí)自動(dòng)HeapDump,這也是生產(chǎn)系統(tǒng)中最可行的HeapDump生成方法。涉及參數(shù)包括:設(shè)置JVM啟動(dòng)時(shí)的環(huán)境變量:exportIBM_HEAP_DUMP=trueexportIBM_HEAPDUMP=trueexportIBM_HEAPDUMP_OUTOFMEMORY=trueexportIBM_JAVADUMP_OUTOFMEMORY=trueexportIBM_JAVACORE_OUTOFMEMORY=true設(shè)置JVM啟動(dòng)參數(shù):-XX:+HeapDumpOnOutOfMemoryError-Xdump:java+system:events=systhrow,filter=java/lang/OutOfMemoryError,range=1..4,request=exclusive+compact+prepwalk:設(shè)置在前4個(gè)OutOfMemoryError時(shí)進(jìn)行HeapDump;基于OS和JDK命令:通過(guò)OS命令gencore生成進(jìn)程COREDUMP,然后通過(guò)JDK命令工具jextract獲取HeapDump;此方法較為復(fù)雜,并不建議用于生產(chǎn)環(huán)境;建議基于JVM事件獲取HeapDump。GC信息GC參數(shù)在不同JVM的或不同JVM版本中均有不同,但一般能夠支持下列參數(shù),系統(tǒng)運(yùn)行時(shí)可以設(shè)置GC日志文件以收集GC信息供后續(xù)分析:-Xloggc:gc.log:指定將gc的信息輸出到gc.log中;-verbose:gc:輸出詳盡的GC信息,通常verbose都只能用于開(kāi)發(fā)調(diào)試環(huán)境,而不應(yīng)該用于生產(chǎn)環(huán)境;-XX:+PrintGC:輸出GC的簡(jiǎn)要信息;-XX:+PrintGCDetails:GC的詳細(xì)信息;-XX:+PrintGCTimeStamps:GC的時(shí)間信息;-XX:+PrintGCApplicationStoppedTime:GC造成的應(yīng)用暫停的時(shí)間;-XX:+PrintTenuringDistribution:GC信息可以提供簡(jiǎn)要的GC運(yùn)行過(guò)程信息,但不太容易基于GC信息判斷JVM有什么異常狀態(tài),因此GC信息收集方法僅供參考。JVM遠(yuǎn)程監(jiān)測(cè)jvisualvm只能遠(yuǎn)程連接啟用了JMX遠(yuǎn)程監(jiān)測(cè)的JVM,JVM啟動(dòng)時(shí)需要設(shè)置一些系統(tǒng)屬性來(lái)啟用JMX遠(yuǎn)程監(jiān)測(cè)。JVM中JMX相關(guān)的配置文件及說(shuō)明位于固定位置,一般位于“JDK/jre/lib/management”,其中有JMX配置的模板文件。因?yàn)橐话鉐DK在服務(wù)器上是公用的,因此不應(yīng)該直接在此位置更改JMX配置,而應(yīng)該復(fù)制其中的文件后更改,并在JVM的啟動(dòng)參數(shù)中指定使用更改后的文件。在JVM啟動(dòng)參數(shù)中指定JMX配置文件的方式為:-Dcom.sun.management.config.file=<somewhere>.perties,JMX的配置信息在此文件中設(shè)置,下面描述JMX配置文件中的典型配置。無(wú)認(rèn)證方式啟用JMX并且不進(jìn)行認(rèn)證,此時(shí)任何JMX客戶端都可以遠(yuǎn)程連接到此JVM進(jìn)行遠(yuǎn)程監(jiān)測(cè),因此安全性很差,但在開(kāi)發(fā)調(diào)試和測(cè)試環(huán)境中較為方便。在JVM啟動(dòng)參數(shù)中設(shè)置“-Dcom.sun.management.config.file=C:\JMXRemote\perties”,同時(shí)在JMX配置文件(C:\JMXRemote\perties)中設(shè)置下面的值:#設(shè)置JMX端口號(hào),JMX客戶端連接時(shí)使用此端口com.sun.management.jmxremote.port=9999#設(shè)置JMX不使用SSL連接com.sun.management.jmxremote.ssl=false#設(shè)置JMX客戶端連接本JVM時(shí)無(wú)需身份認(rèn)證com.sun.management.jmxremote.authenticate=false上述設(shè)置后啟動(dòng)JVM,則任何JMX客戶端均可以連接此JVM并進(jìn)行JVM運(yùn)行狀態(tài)監(jiān)測(cè)。認(rèn)證方式啟用JMX且需要身份認(rèn)證,只有認(rèn)證通過(guò)的JMX客戶端才能夠連接到此JVM進(jìn)行監(jiān)測(cè)。在JVM啟動(dòng)參數(shù)中設(shè)置“-Dcom.sun.management.config.file=C:\TEMP\JMXRemote\auth\perties”,并在此文件中設(shè)置下列值:#設(shè)置JMX端口號(hào),JMX客戶端連接時(shí)使用此端口com.sun.management.jmxremote.port=9999#設(shè)置JMX不使用SSL連接com.sun.management.jmxremote.ssl=false#設(shè)置JMX客戶端連接本JVM時(shí)需要身份認(rèn)證com.sun.management.jmxremote.authenticate=true#設(shè)置身份認(rèn)證文件地址com.sun.management.jmxremote.password.file=C:/TEMP/JMXRemote/auth/jmxremote.password#設(shè)置角色文件地址com.sun.management.jmxremote.access.file=C:/TEMP/JMXRemote/auth/jmxremote.access注意:access和password文件必須正確設(shè)置才能生效,建議只改動(dòng)password文件中的口令以避免其他錯(cuò)誤。而且jmxremote.password文件必須正確設(shè)定其在文件系統(tǒng)中的權(quán)限,否則JVM無(wú)法啟動(dòng),通常需要設(shè)置為此文件只有所有者能夠訪問(wèn)。如果需要設(shè)置JMXServer的監(jiān)聽(tīng)地址,可以設(shè)置下列參數(shù):-Djava.rmi.server.hostname=x.x.x.x"上述設(shè)置后啟動(dòng)JVM,則任何JMX客戶端均可以連接此JVM并進(jìn)行JVM運(yùn)行狀態(tài)監(jiān)測(cè)。常用工具簡(jiǎn)述Java相關(guān)的常用工具及參考位置。jvisualvmjvisualvm是SUN/OracleJDK自帶的JVM運(yùn)行狀態(tài)監(jiān)測(cè)工具,能夠獲取JVM運(yùn)行狀態(tài)的各種信息,包括ThreadDump和HeapDump,在可以使用的情況下建議使用此工具監(jiān)測(cè)JVM運(yùn)行狀態(tài)。連接遠(yuǎn)程JVM當(dāng)設(shè)置了JMX遠(yuǎn)程監(jiān)測(cè)后啟動(dòng)JVM(如啟動(dòng)Tomcat)后,可以在其他機(jī)器上用jvisualvm遠(yuǎn)程監(jiān)測(cè)此JVM(如Tomcat),過(guò)程如下:?jiǎn)?dòng)jvisualvm,增加遠(yuǎn)程主機(jī)(即配置了JMX的JVM所在的主機(jī)),如下圖:輸入遠(yuǎn)程主機(jī)地址,如下圖:確定后,增加JMX連接,如下圖:輸入JMX連接信息,JMX端口信息即是com.sun.management.jmxremote.port=9999中設(shè)定的端口號(hào),如下圖:確定后,如果JMX配置為無(wú)認(rèn)證需求,則連接完成;否則將要求輸入JMX連接用戶名和口令,即在文件com.sun.management.jmxremote.password.file=<password_file>中設(shè)置的用戶名和口令。如下圖:用戶名和口令驗(yàn)證成功后連接完成,如下圖:獲取ThreadDump直接在jvisualvm中獲取ThreadDump,如下圖:ThreadDump的結(jié)果如下圖:在其中進(jìn)行ThreadDump分析即可。獲取HeapDump直接在jvisualvm中獲取HeapDump,如下圖:執(zhí)行HeapDump后將提示HeapDump創(chuàng)建位置,如下圖:確定后將創(chuàng)建HeapDump文件,之后在MAT中分析此文件即可。EclipseMemoryAnalyzerTool,MATMAT是JavaHeapDump文件的分析工具,在出現(xiàn)OutOfMemoryError的情況下,通過(guò)MAT可以幫助準(zhǔn)確定位內(nèi)存溢出原因。IDMAIX環(huán)境中生成的COREDUMP文件不是MAT默認(rèn)識(shí)別的.hprof文件格式,需要在MAT中安裝IBMDTFJ插件才能夠打開(kāi)并分析IBMDUMP文件。由于完整的JavaHEAPDUMP文件通常較大(1G以上),因此MAT通常在64位機(jī)器和JDK上才足夠進(jìn)行分析,因此應(yīng)該使用64位MAT并在MemoryAnalyzer.ini配置文件中設(shè)置足夠大的-Xmx參數(shù)。后文的內(nèi)存溢出場(chǎng)景分析全部基于MAT。MAT本身的幫助信息簡(jiǎn)短扼要,下面簡(jiǎn)單介紹幾個(gè)常用的功能。打開(kāi)HeapDump及LeakSuspectsReportsMAT中打開(kāi)HeapDump文件后,將提示是否進(jìn)行內(nèi)存泄漏分析并產(chǎn)生報(bào)告,一般這個(gè)分析都能發(fā)現(xiàn)可能的泄漏點(diǎn),建議進(jìn)行分析,如下圖:分析結(jié)果如下圖,其中描述了可能的泄漏點(diǎn):如果報(bào)告中提示“ThestacktraceofthisThreadisavailable.Seestacktrace.”,則說(shuō)明疑似泄漏點(diǎn)有ThreadStack信息,這是最理想的情況,幾乎可以立刻發(fā)現(xiàn)可能的內(nèi)存泄漏點(diǎn)代碼位置,如下圖:上面紅線位置的jsp應(yīng)該就是泄漏點(diǎn)。但HeapDump中不一定都包含ThreadStack信息,比如IBM的.phd格式的HeapDump中就不包含ThreadStack。通常JDK6+HotSpotJVM的HeapDump(.hprof)和IBMJ9生成的COREDUMP文件中會(huì)包含ThreadStack,因此建議獲取最完整的HeapDump文件進(jìn)行分析。查看Heap中的對(duì)象Heap中的對(duì)象是HeapDump中的主要內(nèi)容,可以查看HeapDump中的全部對(duì)象,如下圖:查看結(jié)果如下圖:可以在其中查詢?nèi)我釩lass,如下圖:可以查看某個(gè)類型的對(duì)象集合,如下圖:實(shí)例信息如下圖:之后可以查看每個(gè)對(duì)象的內(nèi)容,并判斷是否是應(yīng)該存在的對(duì)象。查看DominatorTree簡(jiǎn)單地說(shuō),DominatorTree是對(duì)象引用關(guān)系圖的子集,通過(guò)DominatorTree可以很清晰地發(fā)現(xiàn)“大對(duì)象”,即從此“大對(duì)象”開(kāi)始占用大量?jī)?nèi)存的對(duì)象集合。查看DominatorTree,如下圖:DominatorTree數(shù)據(jù)如下圖,可以清楚地看見(jiàn)占用內(nèi)存最大的對(duì)象子集:之后分析這個(gè)對(duì)象包含的其他對(duì)象關(guān)系,如下圖:通常DominatorTree有助于找到這些占用大量?jī)?nèi)存的對(duì)象子集并進(jìn)行分析。查看線程信息如果ThreadDump中線程信息可用,可以直接查看線程相關(guān)信息,如下圖:線程相關(guān)信息如下圖:圖中紅線標(biāo)識(shí)的部分是線程對(duì)象及其引用其他對(duì)象共占用的內(nèi)存,可以看出此值過(guò)大,可以對(duì)此線程對(duì)象進(jìn)行分析以找到占用這些內(nèi)存的原因。場(chǎng)景分析示例下面列舉一些場(chǎng)景并分析其可能存在的問(wèn)題。JVM內(nèi)的Deadlock與ThreadDumpJVM可以檢測(cè)到synchronized導(dǎo)致的死鎖,考慮下面的代碼:publicclassClassA{ publicclassClassA{ publicstaticStringmonitor1="monitor1"; publicstaticStringmonitor2="monitor2"; publicstaticvoidmain(String[]args){ Threadthread1=newThread(newRunnable(){ publicvoidrun(){ try{ synchronized(monitor1){ System.out.println(Thread.currentThread().getName()+":gotmonitor1"); Thread.sleep(5000); synchronized(monitor2){ System.out.println(Thread.currentThread().getName()+":gotmonitor2"); }

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論