Java性能調優

pooi 9年前發布 | 22K 次閱讀 Java Java開發

調優的方法

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

一般性的調優準則

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

了解Java的動態調優機制

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

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

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

    堆的大小調整

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

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

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

      一個特定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 串行垃圾回收(對小的應用和系統)
      • </ul> 其它調優參數

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

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

        • 使一個shell中新的進程使用libumem
        • </ul>

          LD_PRELOAD=/usr/lib/libumem.so

          • 在sh中使用libumem來啟動Java程序
          • </ul>

            LD_PRELOAD=/usr/lib/libumem.so java java-settings application-args

            • 在csh中使用libumem來啟動Java程序
            • </ul>

              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

              </blockquote> 并行的old generation收集

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

              </blockquote> 使用256MB內存頁

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

              </blockquote> 比較激進的優化

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

              </blockquote> 使用有偏向性的鎖策略

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

              </blockquote> 低延遲和高吞吐

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

              </blockquote> 監控和性能測量

              討論監控(抽取一個程序運行的粗略統計數據)和性能測量(借助工具獲得程序運行性能的細節)是需要單獨的白皮書來論述的。這里借助一些例子來說明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之后,開發人員就擁有了一整套設計模塊。使用它們開發多線程應用程序將變得事半功倍

 本文由用戶 pooi 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!