Java性能調優

轉自:http://blog.chinaunix.net/uid-7177878-id-265123.html

調優的方法

這一節包含了你調優Java應用可以採用的不同選擇。基於這些選擇的比較應該採用我們剛纔討論的統計學方法來進行。

一般性的調優準則

這裏是一些基本的調優準則,幫助你把不同的調優方法進行分類。

瞭解Java的動態調優機制

在你開始調優Java啓動的命令行參數之前,請注意,Sun HotSpotTM Java虛擬機具備了調整自身的特性。這種智能的自我調整稱爲“Ergonomics”。大多數具備2顆CPU和2G以上物理內存的機器都可以被看成是服務器級別(server-class)的機器。這意味着一下選項被缺省打開:

  • -server 編譯器
  • -XX:+UseParallelGC 並行的垃圾回收
  • -Xms 初始堆大小爲機器物理內存的1/64
  • -Xmx 堆大小的上限是機器物理內存的1/4 (不超過1G)

請注意,32位的Windows系統都缺省使用-client編譯器,64位系統如果滿足上面標準的話被認爲是server-class機器。

堆的大小調整

儘管“Ergonomics”機制大大提升了許多應用“開箱即得”的性能,我們仍然需要對Java內存大小調整有足夠的重視。

一個Java應用程序可以使用的最大的堆的大小取決於下面三個因素:

  • 進程數據模型(32-bit還是64-bit),以及相應的操作系統限制
  • 系統可用的虛擬內存
  • 系統可用的物理內存

一個特定Java應用程序的堆的大小不可能超過進程數據模型的最大虛擬內存限制。對於一個32位的進程模型,虛擬內存的地址大小是4G,然而有些操作系統會限制到2G或3G。典型的堆的最大設定值是:-Xmx3800m (1600m - 2G的情況),具體的限制和應用本身也有關。對於64位進程模型,最大值基本上可以認爲沒有限制。對於一個特定機器上的Java應用,Java堆的大小永遠不能設成物理內存的大小,因爲額外的內存需要保留給操作系統,其他進程,甚至其他的Java虛擬機使用。使用太多的系統內存很容易引起虛擬內存和磁盤之間的交換,特別是在垃圾回收的時候,導致嚴重的性能問題。在那些有多個Java應用的環境,或者多個應用的環境裏,這些進程的堆的總和不應該超過系統物理內存的大小。

另一個非常重要的可調參數是Young Generation(也就是NewSize)的大小。通常來講,Young Generation的最大值是堆大小的3/8。

垃圾回收策略

JavaTM平臺提供了垃圾回收算法的選擇。對於每一種算法存在有許多個可調參數。通常來說,下面的前兩個是大型服務器應用最常用的選擇:

  • -XX:+UseParallelGC 並行(吞吐)垃圾回收
  • -XX:+UseConcMarkSweepGC 併發(低暫停時間)垃圾回收
  • -XX:+UseSerialGC 串行垃圾回收(對小的應用和系統)
其它調優參數

通過適當地設置操作系統內存頁面以及使用命令行參數-XX:+UseLargePages以及-XX:LargePageSizeInBytes,你可以從你的系統的內存管理系統中得到最好的效率。請注意,大的PageSize使我們能夠更好地利用虛擬內存資源(TLB),但是這也使得Permanent Generation和Code Cache的尺寸變大,從而迫使你減小Java內存堆的大小。對於2MB或者4MB的內存頁面問題或許不大,但是對於256MB的內存頁,就值得仔細推敲了。

一個針對Solaris環境的例子就是選擇libumem作爲內存堆的分配器。爲了體驗libumem,你可以通過設置LD_PRELOAD環境變量來完成:

  • 使一個shell中新的進程使用libumem
LD_PRELOAD=/usr/lib/libumem.so
  • sh中使用libumem來啓動Java程序
LD_PRELOAD=/usr/lib/libumem.so java java-settings application-args
  • csh中使用libumem來啓動Java程序
env LD_PRELOAD=/usr/lib/libumem.so java java-settings application-args
通過pldd或者pmap命令,你可以確定libumem是否被使用。
調優實例高吞吐量

java -Xmx3800m -Xms3800m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20

並行的old generation收集

java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:+UseParallelOldGC

使用256MB內存頁

java -Xmx2506m -Xms2506m -Xmn1536m -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:+UseParallelOldGC -XX:LargePageSizeInBytes=256m

比較激進的優化

java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:+UseParallelOldGC -XX:+AggressiveOpts

使用有偏向性的鎖策略

java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:+UseParallelOldGC -XX:+AggressiveOpts -XX:+UseBiasedLocking

低延遲和高吞吐

java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:ParallelGCThreads=20 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:SurvivorRatio=8 -XX:TargetSurvivorRatio=90 -XX:MaxTenuringThreshold=31

監控和性能測量

討論監控(抽取一個程序運行的粗略統計數據)和性能測量(藉助工具獲得程序運行性能的細節)是需要單獨的白皮書來論述的。這裏藉助一些例子來說明Java性能調優時可以用到的工具。

監控

Java平臺本身包含大量的監控工具,最流行的是JConsole和jvmstat

性能測量

Java平臺本身包含一些性能測量工具,最流行的是-Xprof Profiler和HPROF Profiler。一個基於JFluid技術的profiler插件被集成���了NetBeans環境裏面。

寫高性能的代碼

NIO(New I/O)API針對內存映射文件和可擴展的網絡操作,提供了更好的性能。通過使用NIO,那些頻繁使用內存或網絡的應用程序將得到巨大的性能提升。一個很好的例子就是Glassfish當中的Grizzly Web Container。

另一個影響程序性能的Java新特性是Concurrency Utilities。越來越多的應用跑在了多CPU多核的服務器上。爲了充分利用這一特性,程序必須設計成多線程的。傳統的多線程編程架構過於複雜,線程之間的交互容易引起錯誤。有了Concurrency Utilities之後,開發人員就擁有了一整套設計模塊。使用它們開發多線程應用程序將變得事半功倍
發佈了32 篇原創文章 · 獲贊 17 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章