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