版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、HP-UX中的Java應(yīng)用性能調(diào)優(yōu)概述HP-UX中的Java應(yīng)用性能調(diào)優(yōu)簡介本指南旨在為讀者提供一系列有用的方法來排除與Java相關(guān)的性能問題,并幫助在HP-UX系統(tǒng)中進(jìn)行Java應(yīng)用的性能調(diào)優(yōu)。本文并沒有詳細(xì)地討論這一課題,只是為該領(lǐng)域的工作進(jìn)行了概述。參考資料部分提到了幾本關(guān)于Java性能調(diào)優(yōu)相關(guān)的書籍和參考文章,可以參閱它們來了解更多詳細(xì)信息。本文的內(nèi)容與包含HotSpot Runtime編譯器版本1.3.1的Java Software Developer Kit(SDK)1.3.1及以后版本保持一致。文中討論的許多主題,在下面的網(wǎng)站有更加詳細(xì)的分析 Performance Tuning
2、 on HP-UX”)或直接訪問在許多報(bào)告有性能問題的情況中,對垃圾回收行為的調(diào)查表明JVM運(yùn)行的heap配置存在問題。在其它情況中,也可能是應(yīng)用的線程鎖定或內(nèi)存溢出引起了該問題。我們建議初學(xué)者采用以下方法的結(jié)合來解決JAVA應(yīng)用性能的問題:l 使用Glance/gpm工具來找出瓶頸所在l 分析Xverbosegc(來自垃圾回收器的詳細(xì)報(bào)告)JVM選項(xiàng)的輸出結(jié)果;l 使用Hpjmeter工具分析Xeprof(擴(kuò)展的簡檔描述)JVM選項(xiàng)的輸出結(jié)果;l 瀏覽kill 3 命令的幾個(gè)輸出結(jié)果它們將提供有用的數(shù)據(jù),可以幫助您對碰到的問題進(jìn)行徹底的初始分析。本文將會對這些領(lǐng)域進(jìn)行深入的分析。以上所述四種
3、方法,以及對硬件設(shè)置、操作系統(tǒng)和JVM版本及選項(xiàng)的詳細(xì)描述,是性能工程師著手解決問題時(shí)最初的一些步驟。Glance/gpm是一個(gè)HP的工具,在HP-UX Application Software光盤的軟件包中。它也可以用于其它操作系統(tǒng),例如Solaris和AIX。其它工具,如“top”、“vmstat”、“netstat”和“sar”也提供了類似的性能信息。這些均被記錄在Sauers和Weygant Sauers所著的HP-UX性能調(diào)優(yōu)一書中。鑒于本文的目的,我們將側(cè)重于介紹使用Glance/gpm進(jìn)行系統(tǒng)和進(jìn)程層的監(jiān)視。采用系統(tǒng)化的方法Java性能分析中存在許多的不確定因素。HP-UX內(nèi)核參
4、數(shù)、在運(yùn)行時(shí)指定的JVM選項(xiàng)以及應(yīng)用設(shè)計(jì)等所有一切都會帶來相應(yīng)的影響。正是由于該原因,所以在分析性能問題時(shí)應(yīng)采取從上至下系統(tǒng)化的方法(從最外層的系統(tǒng)角度)并在首次分析時(shí)考慮所有的可能性,這一點(diǎn)非常重要。采取從上至下的方法,我們首先將系統(tǒng)作為一個(gè)整體來考慮(將一臺或多臺協(xié)作的計(jì)算機(jī)作為一個(gè)集合,它們互相之間具有網(wǎng)絡(luò)影響,可能在某些點(diǎn)還存在數(shù)據(jù)庫訪問影響)。在考慮了整個(gè)系統(tǒng)中所有的可變因素之后,我們將分析范圍縮小到單個(gè)計(jì)算機(jī),再進(jìn)一步縮小到該計(jì)算機(jī)中的單個(gè)進(jìn)程,從而找出問題的根本原因。之所以采用從上之下的分析方法,是因?yàn)閷?dǎo)致性能問題的原因可能存在于程序、計(jì)算機(jī)、數(shù)據(jù)源和網(wǎng)絡(luò)等構(gòu)成整個(gè)系統(tǒng)的各個(gè)部分
5、。有多種工具可以幫助我們逐一分析每臺計(jì)算機(jī),HP-UX Glance/gpm便是其中最強(qiáng)大的工具之一,本文后面的部分會再次提到該工具。過去,研發(fā)實(shí)驗(yàn)室進(jìn)行的分析工作發(fā)現(xiàn)性能瓶頸的原因也可能源于非Java的技術(shù)。性能工程師必須時(shí)刻考慮到這一點(diǎn)。系統(tǒng)中各臺計(jì)算機(jī)之間以及計(jì)算機(jī)與其外部數(shù)據(jù)源之間的數(shù)據(jù)交換也必須進(jìn)行檢查。這項(xiàng)工作可以通過使用“netstat”等網(wǎng)絡(luò)與數(shù)據(jù)庫監(jiān)視工具來完成。推薦流程中的步驟包括:l 評估整體的系統(tǒng)配置、吞吐量和負(fù)載情況;l 測量性能(使用我們將進(jìn)一步詳細(xì)介紹的工具);l 分析來自性能測量工具的數(shù)據(jù);l 確定一個(gè)或多個(gè)可能的瓶頸;l 每次僅更改或調(diào)節(jié)一個(gè)項(xiàng)目;l 再次測量
6、性能以檢查該調(diào)節(jié)步驟所帶來的變化。在本文以后的章節(jié)我們將會更加詳細(xì)地分析這些步驟。在分析過程中考慮來自多個(gè)工具的數(shù)據(jù)并反復(fù)核對其輸出結(jié)果也非常重要。例如,Glance/gpm生成的線程信息應(yīng)該與將“kill 3 ”命令應(yīng)用于JVM進(jìn)程時(shí)所看到的線程數(shù)據(jù)一致。較高的吞吐量水平并非總是性能問題的原因所在。許多生產(chǎn)系統(tǒng)在運(yùn)行時(shí)都一直保持高容量的交易流。性能工程師所要面對的真正問題是“進(jìn)程中的瓶頸在哪里,并且它們?nèi)绾伪挥|發(fā)?”為了找出這些瓶頸,有時(shí)候需要為系統(tǒng)添加負(fù)載,再現(xiàn)峰值用戶處理水平時(shí)的負(fù)載,這時(shí)候系統(tǒng)將非常繁忙。有多種工具可以在基于Web的應(yīng)用上實(shí)現(xiàn)這種高負(fù)載,它們將在本文最后的工具章節(jié)中介紹
7、。避免在信息不充分的情況下妄加猜測不經(jīng)過分析和測量便對問題原因作出最初的猜測非常具有誘惑力,特別是在項(xiàng)目小組承受著壓力要解決一個(gè)問題時(shí)。這種情況應(yīng)該避免。通常情況下,我們所作的猜測會造成誤導(dǎo)。相反,我們建議先使用各種工具(Glance/gpm、Hpjmeter、Hpjtune、sar、Xverbosegc和Xeprof的JVM選項(xiàng)等等)來收集性能數(shù)據(jù),在這些工具的數(shù)據(jù)經(jīng)過分析并被了解之后,便可以就所見的癥狀給出原因了。該分析需要一定的時(shí)間,通常性能工程師進(jìn)行性能調(diào)優(yōu)的第一步是先搜集系統(tǒng)運(yùn)行數(shù)據(jù),而不是上來就修改系統(tǒng)參數(shù)。準(zhǔn)備一個(gè)修改記錄非常重要,用于記錄所作出的每一個(gè)變更,以及應(yīng)用變更后所帶來
8、的性能影響。性能工程師非常容易對系統(tǒng)一次進(jìn)行多個(gè)變更,這種情況應(yīng)該避免。因?yàn)槎鄠€(gè)變更、多種結(jié)果以及許多的外部影響因素很容易給工程師造成混亂,所以應(yīng)該以書面的形式將所應(yīng)用的變更記錄下來。測試大型應(yīng)用具有代表性的較小樣本計(jì)算機(jī)編程中的一個(gè)常用故障排除技巧是將問題盡可能分解到能夠反映癥狀的最小代碼塊。但是這種方法在性能分析中卻非常危險(xiǎn),因?yàn)檩^小樣本的行為通常與實(shí)際生產(chǎn)系統(tǒng)有很大差別。建議盡可能在“真實(shí)的”系統(tǒng)上進(jìn)行性能分析,而不是采用大型系統(tǒng)的子集。這可能會占用測試的時(shí)間,但是所獲得結(jié)果的將會更加準(zhǔn)確。在分析一個(gè)系統(tǒng)時(shí),測量工具本身確實(shí)也會對性能產(chǎn)生影響。例如Glance/gpm便是HP-UX系統(tǒng)中
9、的一個(gè)進(jìn)程,它會占用該機(jī)器的一部分CPU資源。我們所使用的工具已經(jīng)盡可能使這種影響將到最低。但我們在使用一個(gè)測量工具時(shí),這種影響總是存在的。將系統(tǒng)作為一個(gè)整體進(jìn)行評估當(dāng)前許多基于web的體系結(jié)構(gòu)可能采用一組計(jì)算機(jī)作為web服務(wù)器層,另一組計(jì)算機(jī)作為應(yīng)用服務(wù)器層以及一個(gè)數(shù)據(jù)庫層。所有這些都通過網(wǎng)絡(luò)連在一起,并互相作用以響應(yīng)每一個(gè)客戶請求(例如通過瀏覽器發(fā)出的請求)。進(jìn)行整體系統(tǒng)評估的主要工具有Glance/gpm(圖形進(jìn)程監(jiān)視)以及類似的工具(如HP PerfView),它能夠顯示單個(gè)計(jì)算機(jī)中操作系統(tǒng)和進(jìn)程的狀態(tài)。Glance/gpm將就計(jì)算機(jī)不同組件的狀態(tài)為工程師提供一個(gè)可視、直觀的評估,例如
10、其CPU負(fù)載、輸入輸出負(fù)載、網(wǎng)絡(luò)流量,以及內(nèi)存消耗率等。在每臺HP-UX計(jì)算機(jī)上使用Glance/gpm工具使工程師能夠清楚地看到參與整個(gè)系統(tǒng)的所有機(jī)器中哪些負(fù)載緊張,哪些比較空閑。下圖顯示了Glance/gpm窗口中最頂層的計(jì)算機(jī)視圖,我們可以看到該計(jì)算機(jī)的“系統(tǒng)時(shí)間”消耗水平非常高,而被使用的“用戶時(shí)間”水平非常低。這表明該計(jì)算機(jī)存在問題。實(shí)際上我們希望有更高的CPU消耗被用于“用戶時(shí)間”(用于執(zhí)行應(yīng)用的時(shí)間),而不是“系統(tǒng)時(shí)間”(用于執(zhí)行操作系統(tǒng)功能的CPU時(shí)間)。機(jī)器中出現(xiàn)這種非常高的“系統(tǒng)時(shí)間”占用率可能是由于操作系統(tǒng)調(diào)用,它們負(fù)責(zé)鎖定被稱為“mutexes”的數(shù)據(jù)結(jié)構(gòu),占用很長的系
11、統(tǒng)時(shí)間來解決爭奪,或者等待訪問這些結(jié)構(gòu)的線程被強(qiáng)制進(jìn)入休眠狀態(tài)。因此以下的情況可能是Java程序中的線程鎖爭奪所引起的,該話題將在本文以后的部分深入討論。到目前為止,我們已經(jīng)知道太多的時(shí)間被用于執(zhí)行系統(tǒng)代碼,而不是應(yīng)用代碼。下一步是檢查機(jī)器中的哪一個(gè)特定進(jìn)程造成了這種情況。圖1:HP-UX中Glance/gpm工具的主窗口Glance主窗口 高系統(tǒng)時(shí)間舉例低用戶CPU時(shí)間高系統(tǒng)CPU時(shí)間從整體系統(tǒng)視圖縮小至單個(gè)計(jì)算機(jī),再進(jìn)一步縮小至特定的進(jìn)程是使用Glance/gpm工具以及其它HP-UX性能分析工具的一個(gè)練習(xí)。它們將在參考1Sauers中詳細(xì)描述。數(shù)據(jù)收集性能分析的第一個(gè)步驟是記下用戶交易執(zhí)
12、行路徑中每一臺計(jì)算機(jī)的機(jī)器設(shè)置(從而找出懷疑對象)。我們需要的信息包括:l 計(jì)算機(jī)中CPU的數(shù)量以及這些CPU的速度(CPU的數(shù)量可以中Glance/gpm中看到)l 物理內(nèi)存的大?。ㄒ部梢栽贕lance/gpm中看到)l 磁盤空間的大?。ㄒ颜加煤涂捎玫娜萘浚凇癲f”命令的輸出結(jié)果中)l 操作系統(tǒng)可調(diào)節(jié)參數(shù)的值(使用Hpjconfig工具可以看到)l 需要的操作系統(tǒng)補(bǔ)?。℉pjconfig也能提供幫助)l 使用的JVM版本(使用“java version”命令可以找到)l 使用的JVM選項(xiàng)(如Xms、-Xmx或其它)。以下表1中是“java version”命令所輸出的Java版本信息的舉例
13、。 Java version 0-releaseJava(TM) 2 Runtime Environment, Standard Edition (build 0-release-010607- 16:53-PA_RISC1.1)Java HotSpot(TM) Server VM (build 1.3.1 0-release-010607-19:35-PA_RISC2.0 PA2.0, mixed mode) 表1. “Java version”命令輸出的Java運(yùn)行時(shí)版本信息以上的每一個(gè)值均能幫助性能工程師測量機(jī)器中Java程序的性能特征。只需簡單
14、地升級至最新的Java SDK版本,升級操作系統(tǒng)并應(yīng)用最新的補(bǔ)丁,或者使用Java運(yùn)行時(shí)的正確選項(xiàng),便能夠解決一部分性能問題了。建議性能工程師先升級至最新的Java SDK版本和最新的補(bǔ)丁,以證明這樣是否能夠改善系統(tǒng)的狀況。下一章(“hp-ux內(nèi)核參數(shù)”)中描述的Hpjconfig工具也能夠檢查是否已經(jīng)應(yīng)用了正確的HP-UX補(bǔ)丁。表2顯示了Java虛擬機(jī)的一種誤用情況。該實(shí)例顯示了用戶使用了較舊、未經(jīng)優(yōu)化的Java運(yùn)行版本(“classic JVM”),它不適合用于服務(wù)器端長期運(yùn)行的應(yīng)用。建議在這種情況下使用默認(rèn)的Java運(yùn)行(“HotSpot JVM”)。 $ java classic Cl
15、assName表2. 使用較舊、低效的Java運(yùn)行時(shí)版本 這種情況應(yīng)該避免。hp-ux內(nèi)核參數(shù)對操作系統(tǒng)進(jìn)行正確的設(shè)置,使其以最優(yōu)的方式來運(yùn)行Java程序極其重要。幾個(gè)HP-UX可調(diào)參數(shù)會影響這一正確的設(shè)置。用于確定這些可調(diào)參數(shù)最佳值的工具是Hpjconfig,它本身也是一個(gè)Java程序。Hpjconfig是一個(gè)免費(fèi)的程序,可以從以下網(wǎng)址下載表3顯示了Hpjconfig的調(diào)用。$ java cp HPjconfig.jar:HPjconfig_data.jar HPjconfig表3. 使用Hpjconfig工具該工具首先檢查運(yùn)行其的計(jì)算機(jī)的型號,然后允許性能工程師來選擇各種不同的應(yīng)用類型,例
16、如“應(yīng)用服務(wù)器”、“Web服務(wù)器”和“WAP服務(wù)器”等。隨后它將就某些HP-UX內(nèi)核可調(diào)參數(shù)應(yīng)該采用的值提出合理的建議。它還能夠?qū)⑤敵鼋Y(jié)果數(shù)據(jù)保存在一個(gè)文件中。然后系統(tǒng)管理員便可以使用SAM系統(tǒng)管理工具將這些推薦的值應(yīng)用到操作系統(tǒng)中。圖2顯示了Hpjconfig的初始界面。此時(shí),工具正在檢查應(yīng)用到當(dāng)前HP-UX系統(tǒng)中的補(bǔ)丁是否適合于Java。性能分析流程Hpjconfig:檢查補(bǔ)丁圖2:HP-UX系統(tǒng)中Hpjconfig工具的主界面圖3顯示了針對特定應(yīng)用類型所推薦的內(nèi)核參數(shù)舉例,如Hpjconfig工具中所見。性能分析流程Hpjconfig:內(nèi)核參數(shù)更新至推薦的值圖3:Hpjconfig工具的
17、HP-UX內(nèi)核參數(shù)窗口了解有關(guān)這些參數(shù)進(jìn)一步的詳細(xì)信息,請?jiān)L問中國惠普公司技術(shù)動(dòng)力社區(qū)并在技術(shù)論上進(jìn)行交流:27/partnerportal/solutioncommunity.aspx請注意Hpjconfig窗口“推薦的調(diào)整值”一列中所顯示的值僅僅是一些建議。如果一臺計(jì)算機(jī)上運(yùn)行了多個(gè)應(yīng)用進(jìn)程或數(shù)據(jù)庫進(jìn)程, 那么HP-UX內(nèi)核可調(diào)參數(shù)的最優(yōu)值將需要在Java程序以及共享這臺機(jī)器的其它程序之間實(shí)現(xiàn)平衡。對Java程序最為重要的具體HP-UX內(nèi)核可調(diào)參數(shù)包括:l max_thread_proc 決定任何單個(gè)進(jìn)程中所允許的最大線程數(shù)量;l maxdsiz 決定任何
18、進(jìn)程的數(shù)據(jù)段大??;l maxfiles 為任何進(jìn)程能夠打開的最大文件數(shù)量指定一個(gè)軟限制;l maxfiles_lim 為任何進(jìn)程能夠打開的最大文件數(shù)量指定一個(gè)硬限制;l ncallout 決定I/O等待的最大超時(shí)值;l nfile 決定計(jì)算機(jī)系統(tǒng)中所能打開的最大文件數(shù)量;l nkthread 決定計(jì)算機(jī)系統(tǒng)支持的最大內(nèi)核線程數(shù)量;l nproc 指定計(jì)算機(jī)系統(tǒng)中所允許的最大進(jìn)程數(shù)量垃圾回收J(rèn)ava程序需要一定的對象,它們運(yùn)行時(shí)將會占用部分內(nèi)存。這些對象可能在程序開始運(yùn)行時(shí)創(chuàng)建,也可能在程序運(yùn)行過程中創(chuàng)建。在創(chuàng)建一個(gè)新的Java語言對象時(shí),分配給它的內(nèi)存將被放置在一個(gè)被稱為“heap”的區(qū)域。該
19、heap內(nèi)存的大小是有限制的。對于任何JVM運(yùn)行其默認(rèn)最大值被設(shè)定為128MB,除非用戶使用JVM選項(xiàng)mx或Xmx調(diào)整了最大值。以下命令將以默認(rèn)的heap大小值來運(yùn)行JVM(未指定選項(xiàng))。$ java ClassName(ClassName是該應(yīng)用的開始類)表4. 以默認(rèn)的128Mb最大heap值運(yùn)行Java以下命令限制該第二個(gè)JVM運(yùn)行至多占用240MB的heap大小。 $ java Xmx240m ClassName表5. 帶有240Mb最大heap值的Java運(yùn)行在第二個(gè)程序試圖為對象分配內(nèi)存(創(chuàng)建新的對象)時(shí),如果對象需要占用超過240Mb的內(nèi)存,那么JVM將會產(chǎn)生一個(gè)異常信息“Out
20、OfMemoryException”,程序的執(zhí)行便會終止。Java程序與C或C+程序不同,它不會顯式地重新分配或釋放占用的heap內(nèi)存(而C/C+程序器會使用“delete”運(yùn)算符來釋放內(nèi)存)。這是由JVM本身來完成的,而不是程序。JVM通過確保程序的任何部分都不再引用該對象,從而檢測到程序已經(jīng)不再使用該對象。清除不再使用的對象被稱為“垃圾回收”,它可以被視為JVM運(yùn)行間隔期間的一種分離、獨(dú)立的活動(dòng)。這些間隔由多種因素決定,其中之一便是要求更多的heap空間。該內(nèi)存管理策略的影響是一旦決定JVM的垃圾回收應(yīng)該開始,執(zhí)行Java字節(jié)代碼的所有其它線程,無論是解釋或編譯的形式,在垃圾回收過程期間都
21、必須返回至安全點(diǎn)并停止。如果該過程持續(xù)較長的時(shí)間,那么它便會給Java程序的性能造成嚴(yán)重影響。由于這個(gè)原因,在分析Java程序的性能時(shí),分析垃圾回收的行為總是非常重要。圖4顯示了單個(gè)JVM在一臺8CPU的計(jì)算機(jī)上執(zhí)行的過程中,垃圾回收活動(dòng)發(fā)生時(shí)的瞬間影響??梢钥吹?,只有一個(gè)CPU正在執(zhí)行有用的工作,即垃圾回收器本身。其它的CPU幾乎未被使用。Glance屏幕 垃圾回收的影響圖4:在運(yùn)行HP-UX的8CPU系統(tǒng)上,Glance/gpm工具的CPU屏幕中看到的垃圾回收因此過多的垃圾回收活動(dòng)是造成Java程序緩慢的重要原因,所以必須通過評估和更改影響heap的JVM選項(xiàng)來進(jìn)行調(diào)整,選項(xiàng)包括-Xms、
22、-Xmx、-Xmn和XX:SurvivorRatio。但是,第一步是檢查JVM的垃圾回收部分是否發(fā)生了過多的活動(dòng)。在Glance/gpm的主窗口中我們可以獲得很好的線索,來判斷垃圾回收活動(dòng)是否頻繁。如下圖5所示“尖峰”狀的CPU行為類型能夠表明出現(xiàn)了我們不希望的垃圾回收活動(dòng)。圖5表明用戶程序時(shí)間在垃圾回收器接管CPU后經(jīng)歷了非常大的下跌。Glance 頻繁的垃圾回收圖5:HP-UX Glance/gpm工具中“尖峰”狀的CPU行為類型由于我們擁有JVM的“-Xverbosegc”選項(xiàng),這一檢測工作可以通過HP-UX上的Java輕松實(shí)現(xiàn),該選項(xiàng)的使用方式如下。 $ java Xverbosegc
23、:file=myfile.out ClassName表6. 利用-Xverbosegc運(yùn)行Java這使JVM能夠在文件“myfile.out”(文件名僅僅是這里的舉例)中生成詳細(xì)的垃圾回收器數(shù)據(jù)。注:該選項(xiàng)在運(yùn)行時(shí)對JVM只有非常低的影響(除了向磁盤寫入輸出數(shù)據(jù)造成的影響),所以必要時(shí)可以在生產(chǎn)應(yīng)用上使用。輸出數(shù)據(jù)(在上例所說的“myfile.out”文件中)很難讀懂,因?yàn)槠湓几袷饺缦拢?表7. JVM“Xverbosegc”選項(xiàng)的輸出結(jié)果該輸出文件中有19列數(shù)據(jù),描述了垃圾回收器heap消耗期間的各個(gè)時(shí)間和區(qū)域。針對該輸出文件,推薦下載HPjtune GUI工具(并應(yīng)用如下的命令: $ c
24、at myfile.out |awk f processVerboseGC.awk output.txt表8. 在包含Xverbosegc輸出的文件上運(yùn)行processVerboseGC.awk腳本該命令能夠生成非常用戶友好的輸出文件,示例如下表9所示: GC: Full GC required - reason: Old generation expanded on last scavengeGC: Full 1.985317 s since last: 1.985317 s gc time: 96 ms eden: 1834928-0/3670016 survivor: 120576-0/
25、262144 tenure:2 old: 3204992-2356088/3928064GC: Scav 2.190710 s since last: 0.205393 s gc time: 4 ms eden: 3669968-0/3670016 survivor: 0-120720/262144 tenure:32 old: 2356088-2356088/3928064表9. 在Xverbosegc輸出文件上運(yùn)行processVerboseGC122.awk腳本后的輸出結(jié)果在免費(fèi)下載的HPjtune工具中查看GC數(shù)據(jù)能夠獲得對垃圾回收器行為的圖形化視圖。這是該情形下推薦使用的方法。以上數(shù)
26、據(jù)描述了程序執(zhí)行過程中按順序連續(xù)發(fā)生的3次垃圾回收事件。每次事件發(fā)生的時(shí)間,從程序開始時(shí)間算起,以秒為單位顯示在“Full”或“Scav”之后。即使在了解“eden”、“survivor”、“tenure”和“old”等術(shù)語的含義(將會在下文中解釋)之前,我們也能夠從以上數(shù)據(jù)中獲得許多信息。首先,1次“Full”垃圾回收(GC)事件所占用的時(shí)間要比“Scavenge”或“Scav”垃圾回收更多。如果我們看到很多的“Full GC”條目,例如每分鐘一次甚至更多,那么我們便需要采取一些措施。如果在數(shù)據(jù)中看到一個(gè)條目包含以下內(nèi)容:“Full GC required reason : call to
27、System.gc() or Runtime.gc()”那么我們便知道是用戶的Java代碼或應(yīng)用使用的一些庫或基礎(chǔ)設(shè)施代碼正在顯式調(diào)用垃圾回收器。這種情況永遠(yuǎn)都不應(yīng)該發(fā)生。要解決該問題,我們可以將“call to System.gc() or Runtime.gc()”從代碼中移除,或者使用JVM選項(xiàng)XX:+DisableExplicitGC來禁止它,如下所示:$ java XX:+DisableExplicitGC ClassName表10. 通過禁止顯式調(diào)用垃圾回收器的選項(xiàng)運(yùn)行Java第二,我們在“Full”或“Scav”字符串之后便可以看到從程序啟動(dòng)開始計(jì)算的時(shí)間。該時(shí)間(以秒為單位)累
28、計(jì)程序運(yùn)行的時(shí)間,使我們能夠了解到事件發(fā)生時(shí)程序執(zhí)行的進(jìn)度?!皊ince last”字符串之后是與上一次GC活動(dòng)相隔的時(shí)間?!癵c time”字符串表明了該特定的GC事件完成所用的時(shí)間。我們應(yīng)特別注意這些最后的數(shù)字。一般來說,正常JVM執(zhí)行Full GC的次數(shù)要少于Scavenge GC。Scavenge GC之間的間隔應(yīng)該在5秒左右或更長,并且完成的時(shí)間不應(yīng)超過300-400毫秒。如果Scavenge GC完成的時(shí)間達(dá)到1分鐘甚至更長,那么我們便知道程序暫停了那些執(zhí)行Java字節(jié)代碼的線程至少1分鐘,出現(xiàn)了性能問題。我們應(yīng)該考慮調(diào)整控制heap內(nèi)存使用的JVM選項(xiàng)來解決該問題。這可以通過更改
29、與JVM選項(xiàng)Xms、-Xmx和Xmn相關(guān)的值來實(shí)現(xiàn),如下所述。一旦了解到heap內(nèi)存的哪些區(qū)域正被過度使用或未被充分利用,那么我們便可以更改這些值。這將會在下一章中討論。Full GC可能需要1分鐘甚至更長的時(shí)間,取決于需要執(zhí)行回收的heap空間的大小。一般來說,好的實(shí)踐是對JVM運(yùn)行進(jìn)行配置,使Full GC能夠在1分鐘甚至更短的時(shí)間內(nèi)完成,并且相對于Scavenge GC發(fā)生的次數(shù)更少。每5至10分鐘發(fā)生一次Full GC,每次持續(xù)10秒或更少,以及每隔5-10秒發(fā)生一次較小、持續(xù)時(shí)間很短(300-400毫秒或更少)的Scavenge Gcevery,表明JVM運(yùn)行比較正常。heap內(nèi)存中
30、空間本章節(jié)對heap管理進(jìn)行一定的深入分析。通過了解new和old的對象在JVM整個(gè)heap內(nèi)存中的存放,我們便可以看到該空間被使用的情況。然后我們便可以借助JVM選項(xiàng)Xms、-Xmx和-Xmn來采取措施,從而影響行為的改變。下圖6是JVM中整個(gè)heap內(nèi)存的布局圖。垃圾回收Heap布局圖6:用于Java對象的heap內(nèi)存結(jié)構(gòu)在圖6中我們可以看到在整個(gè)heap內(nèi)存中共有4個(gè)“空間”,有時(shí)也稱“區(qū)域”。垃圾回收這一“分代”類型設(shè)計(jì)的目的是,壽命較短的對象可以在所有時(shí)間內(nèi)一直停留在“New區(qū)域”中,并使用一種快速的算法實(shí)現(xiàn)回收。壽命較長的對象必須尋找合適的方式進(jìn)入“Old區(qū)域”并保留在那里,直到一
31、種較慢的垃圾回收算法找到它,如果它已經(jīng)不再使用,那么便可能被清除掉。在上圖6中我們沒有畫出heap內(nèi)存中的“Permanent區(qū)域”空間,本文不對其進(jìn)行討論。我在這里提到它,以表示完整性。heap內(nèi)存中的“Permanent區(qū)域”空間被用于存放永久存在的對象以及其它對象。在Java SDK 1.3.1中其默認(rèn)值是64MB。這一默認(rèn)的最大值,加上默認(rèn)的新和舊區(qū)域的最大值(分別為16和64Mb)便構(gòu)成了整個(gè)heap默認(rèn)的128MB最大值,前文中已經(jīng)提到。Scavenge GC在“New區(qū)域”中完成,因此速度更快。Full GC同時(shí)包含了“New”和“Old”的區(qū)域,因此速度比Scavenges要慢
32、?!癗ew”區(qū)域的默認(rèn)起始大小是2MB?!癗ew”區(qū)域的默認(rèn)最大值是16MB?!癘ld”區(qū)域的默認(rèn)起始大小是4MB?!癘ld”區(qū)域的默認(rèn)最大值是48MB,如上圖中的陰影區(qū)域所示。這些大小可以使用下面的選項(xiàng)進(jìn)行更改:l Xms(heap起始大小)l -Xmx(最大heap大小)l Xmn(New區(qū)域的大?。﹍ -XX:SurvivorRatio=(Eden區(qū)域的大小除以“from”或“to”區(qū)域的大小,后兩個(gè)區(qū)域大小相等)JVM選項(xiàng)。以上前3個(gè)選項(xiàng)中每一個(gè)后面都可以跟一個(gè)數(shù)字,表示分配的MB數(shù)。例如,Xmn256m表示為New區(qū)域分配256MB的空間。建議將Xmn的值設(shè)為Xmx值的三分之一。在臨
33、時(shí)對象使用嚴(yán)重的應(yīng)用中,也可以將Xmn的值設(shè)為Xmx值的一半。-Xmn的值需要根據(jù)具體應(yīng)用進(jìn)行適當(dāng)?shù)恼{(diào)節(jié)。“New”區(qū)域中的“Eden”子空間是新的對象初次創(chuàng)建時(shí)用于存放的內(nèi)存空間。這是一個(gè)非常重要的空間,因?yàn)樗杏脩舳x的對象都會在程序運(yùn)行過程中的某個(gè)時(shí)刻出現(xiàn) 可能持續(xù)較長或較短的時(shí)間。以下是一個(gè)Java程序創(chuàng)建Panel類(一個(gè)通用的用戶接口類)的一個(gè)新對象的實(shí)例。這一新的對象會在“Eden”子空間內(nèi)存放一段時(shí)間,如果它在程序中使用很長時(shí)間,此后將被拷貝到其它地方,也許是“Old”區(qū)域。 Panel p = new Panel();表10. 創(chuàng)建Panel類的一個(gè)新對象很自然,Eden空間
34、隨著時(shí)間會被填滿,因?yàn)橛性絹碓蕉嗟男聦ο蟊淮娣诺狡渲?。在Eden區(qū)域被填滿時(shí),一個(gè)Scavenge GC便會啟動(dòng),并將那些當(dāng)前存在引用的對象從Eden區(qū)域拷貝到“to”區(qū)域中?!皌o”空間是兩個(gè)“survivor”空間之一,可用于保留一段時(shí)間正在使用中的對象,延遲它們進(jìn)入“舊”的區(qū)域,直到它們“經(jīng)歷”多次GC事件。另一個(gè)“survivor”空間稱為“from”空間。此時(shí),沒有引用的對象將會被從Eden區(qū)域中清除,從而釋放出它們此前所占用的空間。這些便是被垃圾回收的對象。前一次GC事件中可能在“from”子空間內(nèi)處于等待狀態(tài)的所有對象也會被拷貝到“to”區(qū)域,然后這兩個(gè)空間交換名稱 “from”
35、成為“to”,“to”成為“from”。對象被從“from”和“to”區(qū)域之間來回拷貝,直到到達(dá)一定的拷貝限制,該限制由“MaxTenuringThreshold”變量設(shè)定,如上圖,其默認(rèn)值為32。這意味著對象在“新”的區(qū)域中最多可以“經(jīng)歷”32次Scavenge GC和32次from-to交換名稱活動(dòng),直到最終被“永久化/tenured”并被存放到“Old”區(qū)域中。Old區(qū)域旨在用于存放程序運(yùn)行期間一直存在的對象?,F(xiàn)在我們便能夠較為輕松地理解Xverbosegc的輸出結(jié)果了。以上表8中包含如下內(nèi)容的條目:eden: 1834928-0/3670016表11. processVerboseGC
36、122.awk輸出結(jié)果中的Eden大小數(shù)字表明了該GC事件發(fā)生之前Eden子空間被占用的大?。^前的數(shù)字),該事件后Eden空間被占用的大?。^后的數(shù)字)以及整個(gè)Eden空間大?。ā?”標(biāo)記后的數(shù)字)。該條目的含義如下:l 該GC活動(dòng)之前新對象占用了1834928字節(jié)的Eden空間。l 作為該GC操作的一部分,這些對象被完全從Eden中移除(被存放到其它地方),因?yàn)镚C之后的Eden占用為零(箭頭后的數(shù)字)。l GC完成之后Eden空間的總大小為3670016字節(jié)。相同的讀取方式也可以應(yīng)用到“survivor”和“Old”空間上。在這種情況下,術(shù)語“survivor”指名為“from”和“
37、to”的兩個(gè)子空間的和。每次Scavenge GC時(shí)清理Eden子空間是垃圾回收的一種正常行為。但是,如果我們看到每次Scavenge GC之后“Survivor”的數(shù)字(“from”和“to”)降到零,那么我們便知道某個(gè)地方出現(xiàn)了問題。對象沒有足夠多地在“from”和“to”子空間之間來回拷貝。相反,它們以超出正常的速度被存放到了“舊”區(qū)域中。這一操作可能會導(dǎo)致“舊”區(qū)域最終被充滿并非長時(shí)間存在的對象。這一癥狀稱為“溢出”,如果發(fā)現(xiàn)連續(xù)的GC事件中MaxTenuringThreshold的值都非常低(2-10),便可以確定是這種癥狀。如果我們發(fā)現(xiàn)“New”區(qū)域中沒有足夠的空間來使對象在其中保
38、留合適的時(shí)間,那么我們可以首先使用-Xmn工具來調(diào)整“新”區(qū)域的大小。這將會擴(kuò)大所有“新”區(qū)域子空間的大小,包括“eden”、“from”和“to”。使用方式如下: $ java Xmn160m Xmx480m Xms480m ClassName表12. 使用Xmn、-Xmx和Xms選項(xiàng)運(yùn)行Java,分別指定“新”區(qū)域、最大總heap值和初始heap值的大小建議“New”區(qū)域的大小與整個(gè)heap最大值的比率在1:3到1:2范圍之間,后一數(shù)字被認(rèn)為是非常激進(jìn)的調(diào)整。我們也可以使用JVM選項(xiàng)XX:SurvivorRatio=來調(diào)節(jié)“from”和“to”子空間相對于Eden空間大小的比率,如下所示:
39、$ java Xmn120m Xmx480m Xms480m XX:SurvivorRatio=8 ClassName表13.借助-Xverbosegc選項(xiàng)運(yùn)行Java這會使Eden子空間的大小為“from”或“to”空間的8倍(后兩者的大小相等)。上一實(shí)例中的“新”區(qū)域?qū)⒈环殖梢粋€(gè)96MB的Eden子空間(即12MB的8倍)以及“from”和“to”兩個(gè)大小均為12MB的子空間,總空間為120MB。建議XX:SurvivorRatio選項(xiàng)保留其默認(rèn)值,在JDK 1.3.1中為8。即“Eden”的大小是“from”或“to”子空間的8倍。我們還建議采取以上的操作,目的是減少FullGC的數(shù)量并
40、保持MaxTenuringThreshold的值盡可能接近32。MaxTenuringThreshold的值會隨著垃圾回收器的執(zhí)行而調(diào)整,所以在程序運(yùn)行過程中可能會不同。該值越低,對象便會越容易被從“from”或“to”子空間拷貝到“Old”區(qū)域中。這是我們希望避免的一種情形。因?yàn)镴VM的Xverbosegc選項(xiàng)在較長的時(shí)間內(nèi)會生成非常多的數(shù)據(jù),所以另一個(gè)技巧是將基本的Xverbosegc輸出數(shù)據(jù)導(dǎo)入到電子表格中(如MS Excel)并畫出程序運(yùn)行時(shí)間內(nèi)“新”或“舊”區(qū)域增長率的圖形。該技巧在開發(fā)人員解決方案合作伙伴門戶(DSPP)站點(diǎn)上有詳細(xì)的記錄,地址: 線程、鎖定與爭奪Java是一種編程
41、語言,它允許在程序中輕松地創(chuàng)建線程或異步的過程。但是這可能會給對多線程程序不熟悉的程序員帶來麻煩。無限制地創(chuàng)建線程當(dāng)然是不好的實(shí)踐,應(yīng)該盡量避免。許多應(yīng)用服務(wù)器中間件系統(tǒng)依賴于創(chuàng)建數(shù)千個(gè)線程。HP-UX支持在一個(gè)進(jìn)程中擁有許多線程。線程的數(shù)量取決于HP-UX內(nèi)核參數(shù)“max_thread_proc”的值。該值可以通過執(zhí)行“kmtune”命令來查看,如表14所示。$ kmtune |grep max_thread_proc表14.使用HP-UX kmtune命令查看內(nèi)核可調(diào)參數(shù)的值幸運(yùn)的是,我們有多種工具可以在程序執(zhí)行期間或執(zhí)行結(jié)束后來查看程序的線程行為。這些工具包括Glance/gpm、Hpj
42、meter和被稱為“kill 3”的方法。下面的內(nèi)容將對它們詳細(xì)進(jìn)行介紹。圖7顯示了用戶通過Glance/gpm查看特定Java進(jìn)程(也許在一系列Java進(jìn)程中)并檢查Java程序運(yùn)行中創(chuàng)建的所有線程時(shí)的數(shù)據(jù)圖形。下圖最左邊一列中的TID表示每個(gè)線程的TID或唯一的線程ID。應(yīng)該指出的是JVM本身在啟動(dòng)時(shí)需要11個(gè)線程,它們與用戶程序代碼所需的線程是分開的。圖7:在Glance/gpm中通過進(jìn)程界面查看正在運(yùn)行的Java程序的所有線程Java程序員在使用線程時(shí)面臨的風(fēng)險(xiǎn)包括:l 創(chuàng)建了太多的線程,超出了操作系統(tǒng)的限制。Java程序中會出現(xiàn)“OutOfMemoryException”的錯(cuò)誤信息,
43、或者一個(gè)提示線程過多的消息。這個(gè)問題非常容易解決。主要方法是在系統(tǒng)上使用Hpjconfig工具來查看內(nèi)核參數(shù)“max_thread_proc”的值,并使用SAM(系統(tǒng)管理)工具進(jìn)行修改。Hpjconfig工具可以從HP Java網(wǎng)站免費(fèi)下載。l 一個(gè)線程可能長時(shí)間占用訪問共享資源的鎖,從而導(dǎo)致一些或所有其它的線程不能訪問CPU。圖8顯示了一個(gè)線程占用了其它線程需要訪問的資源時(shí)的問題情形。鎖爭奪是一種測量方式,用于測量多少線程試圖獲得該鎖以及嘗試獲取的頻率。在爭奪很高時(shí),線程需要花時(shí)間等待進(jìn)入對象監(jiān)視器而不是執(zhí)行有用的工作。HP-UX版本Java SDK 1.3.1(或以后版本)中的-Xepro
44、f選項(xiàng)為用戶提供了關(guān)于鎖爭奪的準(zhǔn)確數(shù)據(jù),并且該數(shù)據(jù)可以被Hpjmeter解釋。圖8:控制多個(gè)線程訪問資源的操作系統(tǒng)監(jiān)視器結(jié)構(gòu)線程T1占用了另一線程T2需要訪問的資源A的鎖。線程T2占用了T1需要訪問的資源B的鎖。這兩個(gè)線程進(jìn)入“死鎖”狀態(tài),除非一個(gè)線程讓步,否則程序?qū)⒉荒芾^續(xù)執(zhí)行。這些問題都與應(yīng)用軟件的設(shè)計(jì)相關(guān)。因此,通過修改軟件的結(jié)構(gòu)(涉及重新編譯)基本上便可以解決這類問題了。但是,工程師必須使用能夠發(fā)現(xiàn)這些問題的工具,并通過它們快速發(fā)現(xiàn)問題的原因。我們能夠獲得的有關(guān)線程和鎖爭奪問題的第一個(gè)線索來自Glance/gpm的輸出。在圖9顯示的系統(tǒng)圖形中,過多的CPU時(shí)間被消耗在“系統(tǒng)”時(shí)間(較深
45、顏色)而不是“用戶”時(shí)間(顏色較淺的區(qū)域)上。正常系統(tǒng)中的情形應(yīng)該相反。“用戶”時(shí)間應(yīng)該是CPU花費(fèi)的大部分時(shí)間,因?yàn)檫@一時(shí)間用于執(zhí)行應(yīng)用代碼。圖9: Glance/gpm中看到的系統(tǒng)時(shí)間使用超出正常的證據(jù)這是可能出現(xiàn)了線程和鎖定問題的一個(gè)跡象。然后我們再次使用Glance/gpm來查看系統(tǒng)上各個(gè)獨(dú)立JVM進(jìn)程所使用的單個(gè)系統(tǒng)調(diào)用。我們可以獲得關(guān)于出現(xiàn)鎖爭奪問題的單個(gè)進(jìn)程的圖像,它可能與下圖相似。這里,特定HP-UX操作系統(tǒng)調(diào)用(如“sched_yield”、“ksleep”和“kwakeup”)被調(diào)用的次數(shù)非常高,超出了Glance/gpm“累計(jì)系統(tǒng)調(diào)用計(jì)數(shù)”一列中測量的所有其它調(diào)用。這些調(diào)
46、用可能因JVM版本的不同而有所差異,但是性能工程師必須在最高被調(diào)用列表中查找所有的調(diào)用。圖10中指向“send”和“recv”調(diào)用的系統(tǒng)調(diào)用率的箭頭表明這些調(diào)用的頻率遠(yuǎn)遠(yuǎn)低于“sched_yield”和“ksleep”調(diào)用。而“send”和“recv”的調(diào)用頻率應(yīng)該更高,因?yàn)樗鼈冊谠摶诰W(wǎng)絡(luò)的程序中需要完成主要的工作。如果我們解決了這里明顯的線程爭奪問題(例如,通過圍繞輪詢(polling)線程和線程池模式重新組織線程設(shè)計(jì)),我們將會看到非常高的“send”和“recv”調(diào)用率。圖10:單個(gè)進(jìn)程對特定系統(tǒng)調(diào)用非常高的系統(tǒng)調(diào)用率 可能出現(xiàn)了線程爭奪如果設(shè)計(jì)中每個(gè)對網(wǎng)絡(luò)流量開放的接口都使用一個(gè)線程
47、,那么這種情形的問題便會出現(xiàn)。在同時(shí)建立上百或上千個(gè)網(wǎng)絡(luò)連接的情況下,這可能會導(dǎo)致在線程爭奪上耗費(fèi)非常高的系統(tǒng)開銷。這類問題在過去的設(shè)計(jì)中已通過實(shí)施HP Poll API得到解決。HP Poll API是設(shè)計(jì)應(yīng)用的一種方法,以使用較少的線程。該主題不在本文的討論范圍之內(nèi)。在Java SDK 1.4中也有一個(gè)子系統(tǒng)可用于對異步I/O環(huán)境中的線程進(jìn)行更好的控制。使用KILL 3獲得線程數(shù)據(jù)轉(zhuǎn)儲該方法在分析JVM線程時(shí)十分簡單,但是非常強(qiáng)大。在一個(gè)正在運(yùn)行的JVM進(jìn)程上使用“kill”命令和參數(shù)“-3”或“-s SIGQUIT”不會影響正在運(yùn)行的JVM,只是使它生成一個(gè)關(guān)于其當(dāng)時(shí)所保留線程的所有信息
48、的詳細(xì)轉(zhuǎn)儲。使用Glance/gpm,或者簡單的“ps ef|grep Java”命令來獲得我們想要查看的JVM的進(jìn)程ID。然后下表15中所示的命令將會通過該程序的標(biāo)準(zhǔn)輸出通道生成有關(guān)線程數(shù)據(jù)的全部轉(zhuǎn)儲。# kill 3 3493 (if 3493 were the PID of the running JVM)表15. 在JVM上使用kill 3命令使其進(jìn)行線程轉(zhuǎn)儲在開始調(diào)用JVM時(shí),我們還可以將標(biāo)準(zhǔn)輸出重新定向到一個(gè)文件中。以上的kill命令可能需要用戶具有超級用戶權(quán)限。正在運(yùn)行的JVM生成的標(biāo)準(zhǔn)輸出數(shù)據(jù)(如果超過一定的大小,可能會被要求重新定向到一個(gè)文件),可能與下面的示例相似。圖11:
49、在由指定的運(yùn)行中的JVM進(jìn)程上執(zhí)行“kill 3 ”命令時(shí)的部分輸出數(shù)據(jù)圖11顯示了一個(gè)特定的線程(其輕量進(jìn)程ID,圖中l(wèi)wp_id,為14165)正處于掛起狀態(tài),因?yàn)樗恢痹诘却i以訪問一個(gè)特定的對象(由其十六進(jìn)制地址指定)。這只是一個(gè)較大數(shù)據(jù)轉(zhuǎn)儲的一個(gè)較小的快照,但能夠使讀者了解到這一輸出。在該輸出中我們需要特別注意的是,一個(gè)線程長時(shí)間占用訪問一個(gè)對象的鎖,而該對象需要被其它線程訪問。這導(dǎo)致整個(gè)JVM的速度變慢,從而出現(xiàn)問題。我們可以在問題程序運(yùn)行過程中多次重復(fù)“kill 3 ”操作,以檢查是否是持續(xù)的鎖定造成了該問題。但是,在處理擁有大量線程的程序時(shí),這可能會生成非常多的數(shù)據(jù)。徹底分析所
50、有這些數(shù)據(jù)并從中找出問題非常困難。作為一個(gè)附加的好處,我們可以使用Hpjmeter工具來幫助完成一部分工作。使用hpjmeter工具來檢測線程鎖定問題分析JVM線程行為的一個(gè)更簡單的方法是采用HP特定選項(xiàng)Xeprof運(yùn)行該程序至結(jié)束,然后使用Hpjmeter工具分析其輸出結(jié)果。如果正在JVM中執(zhí)行的程序能夠被完全地終止(即,使用System.exit()或一些適當(dāng)?shù)年P(guān)閉過程),那么JVM必須采用如下擴(kuò)展的分析選項(xiàng)(-Xeprof)來運(yùn)行。$ java Xeprof:file=myfile.eprof ClassName表16.使用Xeprof選項(xiàng)來運(yùn)行Java程序,以便在運(yùn)行中進(jìn)行監(jiān)視我們分析
51、生成到文件(例如f)中輸出結(jié)果的工具是Hpjmeter分析工具,它可以通過以下地址免費(fèi)下載該工具本身以Java語言編寫,因此它可以在任何支持JVM的平臺上運(yùn)行。該工具將讀取標(biāo)準(zhǔn)JVM選項(xiàng)Xprof生成的輸出文件。但是,如果讀取HP JVM特定Xeprof選項(xiàng)生成的輸出文件,那么該工具將能夠帶來更多優(yōu)勢和詳細(xì)信息。運(yùn)行Hpjmeter工具(在HP-UX或任何支持Java的平臺上)的命令如下表17所示。$ java cp /opt/hpjmeter/HPjmeter.jar HPjmeter表17. 運(yùn)行Hpjconfig工具該免費(fèi)的工具除了與線程運(yùn)行時(shí)間相關(guān)的測量方法以外,還
52、擁有許多有用的測量方法。這些測量方法在下載站點(diǎn)的指南中有詳細(xì)的介紹。在本文的該部分中我們僅側(cè)重于使用其進(jìn)行線程分析。Hpjmeter工具生成JVM運(yùn)行中關(guān)于線程狀態(tài)及其運(yùn)行時(shí)間的圖形頁面。我們將Xeprof選項(xiàng)生成的文件載入到工具中,然后選擇名為“Metric”的菜單項(xiàng)顯示線程柱形圖,便可以得到以下的圖形。表12.在Hpjmeter工具中顯示線程運(yùn)行時(shí)間及其狀態(tài)的頁面信息這使我們能夠一次看到所有線程的運(yùn)行時(shí)間,并可以通過雙擊代表線程的彩色條集中于有問題的某個(gè)線程或多個(gè)線程,從而進(jìn)行深入的分析。以上圖中的線程0有77.1%的時(shí)間在CPU內(nèi)執(zhí)行;這是正常的標(biāo)志。該線程有大約21.4%的報(bào)告時(shí)間被用
53、于profiler系統(tǒng)開銷,只有非常少的時(shí)間被用在等待執(zhí)行或鎖爭奪上。使用HP的Java SDK 1.3.1+和HPjmeter 1.2+,我們可以獲得關(guān)于線程爭奪問題的非常準(zhǔn)確的圖形,這些問題可能會降低Java程序的運(yùn)行速度。除了線程分析以外,Hpjmeter在分析許多其它情況時(shí)也非常有用。使用該工具提供的一些測量方法還可以追蹤消耗大量CPU和wall時(shí)鐘時(shí)間的方法(method)。這將會在以后的“昂貴的方法調(diào)用”一章中詳細(xì)討論。線程總結(jié)Java程序線程被Java虛擬機(jī)映射到操作系統(tǒng)線程,也稱HP-UX輕量進(jìn)程(LWP)。HP-UX中調(diào)度單元為單個(gè)的線程。每一個(gè)線程在Glance工具中都是可
54、見的,例如擁有唯一的LWP編號(LWP ID),使用“Thread List”特性。最初,每個(gè)線程優(yōu)先級的初始值與操作系統(tǒng)中的所有用戶進(jìn)程相同。由于線程在CPU中執(zhí)行,在正常條件下,其優(yōu)先級會隨著其獲得更多的CPU時(shí)間而降低。這導(dǎo)致線程在離開CPU時(shí)優(yōu)先級變低。因此操作系統(tǒng)在下一次根據(jù)優(yōu)先級來調(diào)度線程時(shí),該線程相對于其它線程可能會處于不利的地位。如果一個(gè)特定的Java進(jìn)程是一臺計(jì)算機(jī)上唯一最重要的用戶進(jìn)程,那么該進(jìn)程可以通過超級用戶干預(yù),在開始或執(zhí)行過程中被授予最高的調(diào)度優(yōu)先級。這可以分別使用“nice”或“renice”命令來完成,或使用Glance/gpm的“renice”功能?!皀ice”命令如下表18中所示。# nice -20 java ClassName (notice there are 2 minus signs)表18. 使用“nice”命令運(yùn)行Java程序“renice”命令需根據(jù)正在運(yùn)行的Java程序的進(jìn)程ID來執(zhí)行,
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024-2030年中國茶油行業(yè)營銷現(xiàn)狀分析及發(fā)展?jié)摿ρ芯繄?bào)告
- 2024-2030年中國花生奶行業(yè)市場運(yùn)營模式及未來發(fā)展動(dòng)向預(yù)測報(bào)告
- 2024-2030年中國腐乳行業(yè)發(fā)展趨勢及營銷模式分析報(bào)告
- 2024-2030年中國聚丙烯用阻燃劑行業(yè)現(xiàn)狀分析及發(fā)展可行性研究報(bào)告
- 2024-2030年中國翡翠首飾行業(yè)市場運(yùn)營模式及未來發(fā)展動(dòng)向預(yù)測報(bào)告
- 2024-2030年中國維生素A市場銷售態(tài)勢及競爭前景預(yù)測報(bào)告
- 2024-2030年中國紙杯紙碗行業(yè)生產(chǎn)銷售及未來發(fā)展策略分析報(bào)告
- 2024-2030年中國紅薯種植行業(yè)生產(chǎn)銷售模式及發(fā)展前景展望報(bào)告
- 2024-2030年中國竹砧板行業(yè)競爭格局及投資戰(zhàn)略分析報(bào)告
- 2024-2030年中國礦場礦區(qū)水泥用石灰?guī)r礦行業(yè)需求狀況及競爭趨勢預(yù)測報(bào)告
- 實(shí)驗(yàn)室定期自查制度
- 建設(shè)施工合同書證據(jù)目錄
- 7 中華民族一家親 互相尊重 守望相助 教學(xué)設(shè)計(jì)-2024-2025學(xué)年道德與法治五年級上冊統(tǒng)編版
- 2024年高考?xì)v史真題+模擬題專項(xiàng)版匯編專題03古代中國的思想文化與科技含解析
- 中醫(yī)疫病防治
- 2024九年級英語下冊 Unit 7 Work for PeaceLesson 39 Having Good Relationships in Your Community教學(xué)設(shè)計(jì)(新版)冀教版
- 《深?!分械纳蕯⑹屡c鏡像闡釋
- 2023年中考英語備考讓步狀語從句練習(xí)題(附答案)
- JGJ/T235-2011建筑外墻防水工程技術(shù)規(guī)程
- ISO9001:2015內(nèi)部質(zhì)量審核控制程序
- 柔性生產(chǎn)線設(shè)計(jì)
評論
0/150
提交評論