巧解IBM JVM for Linux onPOWER性能調(diào)優(yōu)
你對IBMJVM for Linux onPOWER的性能調(diào)優(yōu)技巧是否了解,這里和大家重點(diǎn)討論一下用于iSeries和pSeries上的IBMJVMforLinux的一些重要性能調(diào)優(yōu)問題,相信本文介紹一定會讓你有所收獲。
IBM JVM for Linux onPOWER的性能調(diào)優(yōu)技巧
本文將介紹用于iSeries和pSeries上的IBMJVMforLinux的一些重要性能調(diào)優(yōu)問題。在撰寫這篇文章的時(shí)候,IBM推出了JDK1.3.132-bit和JDK1.4.2,但無論是32位還是64位風(fēng)格的,都適用于IBMiSeries和pSeries上的Linux。本文中提供的技巧可應(yīng)用于IBMiSeries和pSeries上的IBMJDK1.3.1和JDK1.4.2forLinux,但是本文的特別針對目標(biāo)是最新的IBMJDK版本JDK1.4.2。
編寫性能高效的Java代碼
本文將重點(diǎn)參考針對JDK1.3.1和JDK1.4.2的 IBMJVMDiagnosticsGuides。
這一節(jié)將介紹編寫性能高效Java代碼的一些通用準(zhǔn)則,明確討論如何避免對象創(chuàng)建和垃圾收集(GC),同時(shí)還將討論JNI、同步和數(shù)據(jù)結(jié)構(gòu)。
避免對象創(chuàng)建和GC
只要有可能,應(yīng)該避免創(chuàng)建對象,防止調(diào)用構(gòu)造函數(shù)帶來的相關(guān)性能成本,以及在對象結(jié)束其生命周期時(shí)進(jìn)行垃圾收集所帶來的成本。
考慮以下這些準(zhǔn)則:
只要有可能,就使用基本變量類型,而不使用對象類型。例如,使用int,而不使用Integer。
緩存那些頻繁使用的壽命短的對象,避免一遍又一遍地重復(fù)重建相同的對象,并因此進(jìn)行GC。
在處理字符串時(shí),使用StringBuffer而不使用字符串連接,因?yàn)樽址畬ο缶哂胁豢勺兊奶匦?,并且需要?jiǎng)?chuàng)建額外的字符串對象,而這些對象最終必須經(jīng)歷GC。
避免過度對Java控制臺進(jìn)行寫操作,降低字符串對象處理、文本格式化和輸出帶來的成本。
實(shí)現(xiàn)數(shù)據(jù)庫連接池,重用連接對象,而不是重復(fù)地打開和關(guān)閉連接。
使用線程池(threadpooling)。避免不停地創(chuàng)建和刪除線程對象,特別是在大量使用線程的時(shí)候。
通過System.gc()調(diào)用避免在代碼中調(diào)用GC。GC是一個(gè)“停止所有處理(stoptheworld)”的事件,它意味著除了GC線程自身外,其他所有執(zhí)行線程都將處于掛起狀態(tài)。如果必須調(diào)用GC,那么可以在非緊急階段或空閑階段實(shí)現(xiàn)它。
避免在循環(huán)內(nèi)分配對象,這會使對象在Java堆上的存活時(shí)間超過必要的存活時(shí)間。
Java Native Interface
使用本機(jī)代碼編寫應(yīng)用程序部分,特別是頻繁使用的部分,并將之與Java鏈接,這樣做通常是為了提高性能。不過,JVM與本機(jī)代碼之間的通信通常很慢,因此,太多的JNI調(diào)用可能會降低性能。只要有可能就應(yīng)該將本機(jī)操作集合在一起,以減少JNI調(diào)用的數(shù)量。
使用JNI代碼本地處理異常,盡管有時(shí)不可避免地會導(dǎo)致性能下降。在這種情況下,應(yīng)該使用ExceptionCheck()函數(shù),因?yàn)榕cExceptionOccurred()相比較,它帶來的計(jì)算開銷更少一些。后者必須創(chuàng)建一個(gè)將引用的對象,以及一個(gè)本地引用。
同步
為了減少JVM和操作系統(tǒng)中的爭用,應(yīng)該只在可行的情況下才使用同步方法。不要將同步方法放到循環(huán)結(jié)構(gòu)中。
數(shù)據(jù)結(jié)構(gòu)
作為一條通用規(guī)則,在更簡單的數(shù)據(jù)結(jié)構(gòu)能滿足需要的地方,應(yīng)該避免使用更復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。例如,在可以使用數(shù)組的地方不要使用向量。使用最有效的方法搜索元素,并將元素插入數(shù)據(jù)結(jié)構(gòu)中,比如說,在向量的結(jié)尾處添加和刪除元素,以便獲得更好的性能。
提高性能的編譯選項(xiàng)
用-O優(yōu)化標(biāo)記編譯Java代碼。代碼優(yōu)化提供了以下幾個(gè)好處:
讓代碼變得模糊,使它更難以進(jìn)行“逆向工程(reverse-engineer)”。
極大地增強(qiáng)源代碼的安全性。
極大地減小Java程序的大小。
提高運(yùn)行時(shí)性能#p#
提高性能的環(huán)境設(shè)置
◆Spinloop
目前,通過調(diào)整SPINLOOP變量和時(shí)間片值,可以顯示可獲得的最大性能。IBM_LINUX_SPIINLOOP時(shí)間值是一個(gè)進(jìn)程在鎖定之前可以在某個(gè)繁忙的鎖上自旋的次數(shù)。有三個(gè)SPINLOOP變量可進(jìn)行調(diào)整(從0到100的數(shù)字):
IBM_LINUX_SPINLOOP1
IBM_LINUX_SPINLOOP2
IBM_LINUX_SPINLOOP3
在16路LPAR上執(zhí)行的基準(zhǔn)測試認(rèn)為以下設(shè)置將是最佳設(shè)置:
IBM_LINUX_SPINLOOP1=96
IBM_LINUX_SPINLOOP2=85
IBM_LINUX_SPINLOOP3=85
與其他任何全局變量一樣,需要在shell實(shí)例中設(shè)置這些變量,JVM進(jìn)程將會在這個(gè)實(shí)例中運(yùn)行,因此,可以通過JVM將這些設(shè)置讀取到全局變量表中。
◆Sysctl
在可以運(yùn)行內(nèi)核2.4.19的SLES8上,有一個(gè)用于設(shè)置Linux內(nèi)核中時(shí)間片的最大值和最小值的選項(xiàng)。這些都是通過sysctl命令設(shè)置的。為了獲得好的Java性能,極力推薦將sysctl值sched_yield_scale設(shè)置為1。
路徑
CLASSPATH變量應(yīng)該在搜索路徑的前面包含一些最常使用的Java庫。對于LIBPATHandLD_LIBRARY_PATH變量,也應(yīng)該這樣做,以便獲得最常使用的JNI共享庫。
用戶限制設(shè)置
為了獲得最佳性能,讓運(yùn)行JVM進(jìn)程的用戶擁有經(jīng)過正確配置的用戶設(shè)置是很重要的。這些參數(shù)可以設(shè)置成以下兩種形式之一:
暫時(shí)地,適用于通過ulimit命令登錄shell會話期間。
永久地,通過將一個(gè)相應(yīng)的ulimit語句添加到由登錄shell讀取的文件之一(例如~/.profile),即特定于shell的用戶資源文件;或者通過編輯/etc/security/limits.conf。
建議設(shè)置成無限制(unlimited)的一些重要設(shè)置是:
數(shù)據(jù)段長度:ulimit–dunlimited
最大內(nèi)存大?。簎limit–munlimited
堆棧大?。簎limit–sunlimited
CPU時(shí)間:ulimit–tunlimited
虛擬內(nèi)存:ulimit–vunlimited
對于需要做許多套接字連接并使它們處于打開狀態(tài)的Java應(yīng)用程序而言,最好通過使用ulimit–n,或者通過設(shè)置/etc/security/limits.conf中的nofile參數(shù),為用戶把文件描述符的數(shù)量設(shè)置得比默認(rèn)值高一些。
GC和Java堆
“垃圾收集器”是影響JVM性能的最重要的JVM組件之一。關(guān)于GC和堆大小調(diào)優(yōu)的一般性IBMJVM討論(在針對JDK1.3.1和JDK1.4.2的IBMJVMDiagnosticsGuides中)也可應(yīng)用于IBMJVMonLinux(包括LinuxonPOWER),只是有一些IBMJVMonLinux特定的東西,后面會進(jìn)行討論。
最大堆大小是由–Xmx控制的,在32位IBMJVMforLinux上,可以將該值設(shè)置得比在32位IBMJVMforAIX上的更高一些,因?yàn)檫@兩個(gè)操作系統(tǒng)的內(nèi)存模式有所不同。如果沒有指定–Xmx選項(xiàng),則使用默認(rèn)設(shè)置(即實(shí)際內(nèi)存的一半,最小值是16MB,最大值是512MB)。
如果沒用–Xms選項(xiàng)明確指定初始堆大小,那么該值是默認(rèn)值4MB。有關(guān)GC和Java堆調(diào)優(yōu)的更多信息,請參閱針對JDK1.3.1和JDK1.4.2的IBMJVMDiagnosticsGuides中的“DebuggingPerformanceProblems:JVMPerformance”。“UnderstandingtheGarbageCollector”和“GarbageCollectorDiagnostics”這兩章也值得一看。
JIT
就性能而言,JIT是最重要的JVM組件。關(guān)于IBMJVMJIT的一般性討論,請參閱JVMDiagnosticsGuide中的“UnderstandingtheJIT”小節(jié)。要獲得關(guān)于JIT性能的Linux特定細(xì)節(jié),請參閱“LinuxProblemDetermination”和“JITDiagnostics”的JIT部分。
監(jiān)控JVM
在JVMDiagnosticsGuide的“LinuxProblemDetermination”一章中,詳細(xì)地討論了IBMJVMforLinux性能問題確定、JVM監(jiān)控和一些工具。
以下章節(jié)可能有其他的價(jià)值:
追蹤Java應(yīng)用程序和JVM。
使用JVM監(jiān)控接口(JVMMI)。
使用可靠、可用和可服務(wù)的接口。
使用JVMPI。
使用第三方工具。
Linux線程模型和JVM
以下是一些線程模型實(shí)現(xiàn)方面的詳細(xì)說明,該實(shí)現(xiàn)將影響不同Linux發(fā)行版本上的JVM性能。請參閱JVMDiagnosticsGuide中的“LinuxProblemDetermination”一章,以了解更多細(xì)節(jié)。
另一個(gè)要知道的問題是Linux上的線程浮點(diǎn)堆棧限制,正如JVMDiagnosticsGuide的“FloatingStacksLimitation”小節(jié)中所討論的那樣。
詞匯表
GC,垃圾收集器
JDK,Java軟件包,包括JRE和一些開發(fā)工具
JIT,即時(shí)編譯器
JRE,Java運(yùn)行時(shí)環(huán)境,無開發(fā)工具
JVMMI,Java虛擬機(jī)監(jiān)控接口
JVM,Java虛擬機(jī)
JVMPI,Java虛擬機(jī)分析接口
NPTL,本地POSIX線程庫
OS,操作系統(tǒng)
RHELAS,RedHatEnterpriseLinux高級服務(wù)器版本
SLES,SUSELinux企業(yè)服務(wù)器
SR,服務(wù)刷新
【編輯推薦】