JVM 調優

jopen 8年前發布 | 10K 次閱讀 Java開發

JVM 堆內存分區

堆:年輕代,老年代,持久代

年輕代:Eden,Survivor1,Survivor2

一個性能較好的jvm參數配置以及jvm的簡介

JVM基本回收算法

  1. 引用計數(Reference Counting
    比較古老的回收算法。原理是此對象有一個引用,即增加一個計數,刪除一個引用則減少一個計數。垃圾回收時,只用收集計數為0的對象。此算法最致命的是無法處理循環引用的問題。

  2. 標記-清除(Mark-Sweep
    此算法執行分兩階段。第一階段從引用根節點開始標記所有被引用的對象,第二階段遍歷整個堆,把未標記的對象清除。此算法需要暫停整個應用,同時,會產生內存碎片。

  3. 復制(Copying
    此 算法把內存空間劃為兩個相等的區域,每次只使用其中一個區域。垃圾回收時,遍歷當前使用區域,把正在使用中的對象復制到另外一個區域中。次算法每次只處理 正在使用中的對象,因此復制成本比較小,同時復制過去以后還能進行相應的內存整理,不過出現碎片問題。當然,此算法的缺點也是很明顯的,就是需要兩倍 內存空間。

  4. 標記-整理(Mark-Compact
    此算法結 合了標記-清除復制兩個算法的優點。也是分兩階段,第一階段從根節點開始標記所有被引用對象,第二階段遍歷整個堆,把清除未標記對象并且把存活 對象壓縮到堆的其中一塊,按順序排放。此算法避免了標記-清除的碎片問題,同時也避免了復制算法的空間問題。

  5. 增量收集(Incremental Collecting)
    實施垃圾回收算法,即:在應用進行的同時進行垃圾回收。不知道什么原因JDK5.0中的收集器沒有使用這種算法的。

  6. 分代(Generational Collecting
    基于對對象生命周期分析后得出的垃圾回收算法。把對象分為年青代、年老代、持久代,對不同生命周期的對象使用不同的算法(上述方式中的一個)進行回收。現在的垃圾回收器(從J2SE1.2開始)都是使用此算法的。


JVM常見配置匯總

  1. 堆設置

    • -Xms:初始堆大小(默認值,物理內存的1/64)

    • -Xmx:最大堆大小(默認值,物理內存的1/4)

    • -Xmn:年輕代大小(Sun官方推薦年輕代配置為整個堆的3/8)

    • -XX:NewSize=n:設置年輕代大小

    • -XX:MaxNewSize=n:設置年輕代最大值

    • -XX:NewRatio=n:設置年輕代和年老代的比值。如:為3,表示年輕代與年老代比值為1:3,年輕代占整個年輕代年老代和的1/4。

    • -XX:PermSize=n:設置持久代的大小 (物理內存的1/64)

    • -XX:MaxPermSize=n:設置持久代大小最大值(物理內存的1/4)

    • -XX:SurvivorRatio=n:年輕代中Eden區與兩個Survivor區的比值。注意Survivor區有兩個。如:3,表示Eden:Survivor=3:2,一個Survivor區占整個年輕代的1/5

    • -Xss:每個線程的堆棧大小,JDK5.0以后每個線程堆棧大小為1M,以前每個線程堆棧大小為256K.更具應用的線程所需內存大小進行 調整.在相同物理內存下,減小這個值能生成更多的線程.

    • -XX:+UseBiasedLocking:鎖機制性能改善


  2. 收集器設置

    • -XX:+UseSerialGC:設置串行收集器

    • -XX:+UseParallelGC:設置并行收集器 此配置僅對年輕代有效

    • -XX:+UseParalledlOldGC:設置并行年老代收集器

    • -XX:+UseConcMarkSweepGC:設置并發收集器(參數表示對于老年代的回收采用CMS。CMS采用的基礎算法是:標記—清除。)

    • -XX:ParallelGCThreads=n:設置并行收集器線程數,此值最好與處理器核數相同

    • -XX:MaxGCPauseMillis=n:設置并行收集最大暫停時間(每次年輕代垃圾回收的最長時間,如果無法滿足此時間,JVM會自動調整年輕代大小,以滿足此值.)

    • XX:GCTimeRatio=n:設置垃圾回收時間占程序運行時間的百分比。公式為1/(1+n)

  3. 垃圾回收統計信息

    • -XX:+PrintGC

    • -XX:+PrintGCDetails

    • -XX:+PrintGCTimeStamps

    • -Xloggc:filename

  4. 并發收集器設置

    • -XX:+CMSIncrementalMode:設置為增量模式。適用于單CPU情況。

    • -XX:ParallelGCThreads=n:設置并發收集器年輕代收集方式為并行收集時,使用的CPU數。并行收集線程數。


常見配置:

請看一下一個時間的Java參數配置:(服務器:Linux 64Bit,8Core×16G) 

 JAVA_OPTS="$JAVA_OPTS -server -Xms3G -Xmx3G -Xss256k 

          -XX:PermSize=128m 

          -XX:MaxPermSize=128m 

          -XX:+UseParallelOldGC 

          -XX:+HeapDumpOnOutOfMemoryError 

          -XX:HeapDumpPath=/usr/aaa/dump 

          -XX:+PrintGCDetails 

          -XX:+PrintGCTimeStamps 

          -Xloggc:/usr/aaa/dump/heap_trace.txt 

          -XX:NewSize=1G 

          -XX:MaxNewSize=1G"


?

調優總結?

  1. 年輕代大小選擇

    • 響應時間優先的應用盡可能設大,直到接近系統的最低響應時間限制(根據實際情況選擇)。在此種情況下,年輕代收集發生的頻率也是最小的。同時,減少到達年老代的對象。

    • 吞吐量優先的應用:盡可能的設置大,可能到達Gbit的程度。因為對響應時間沒有要求,垃圾收集可以并行進行,一般適合8CPU以上的應用。

  2. 年老代大小選擇

    • 響應時間優先的應用:年老代使用并發收集器,所以其大小需要小心設置,一般要考慮并發會話率會話持續時間等一些參數。如果堆設置小了,可以會造成內存碎片、高回收頻率以及應用暫停而使用傳統的標記清除方式;如果堆大了,則需要較長的收集時間。最優化的方案,一般需要參考以下數據獲得:

      • 并發垃圾收集信息

      • 持久代并發收集次數

      • 傳統GC信息

      • 花在年輕代和年老代回收上的時間比例

    • 減少年輕代和年老代花費的時間,一般會提高應用的效率

    • 吞吐量優先的應用:一般吞吐量優先的應用都有一個很大的年輕代和一個較小的年老代。原因是,這樣可以盡可能回收掉大部分短期對象,減少中期的對象,而年老代盡存放長期存活對象。

    • CMS調優可針對老年代

  3. 較小堆引起的碎片問題

       因為年老代的并發收集器使用標記、清除算法,所以不會對堆進行壓縮。當收集器回收時,他會把相鄰的空間進行                合并,這樣可以分配給較大的對象。但是,當堆空間較小時,運行一段時間以后,就會出現“碎片”,如果并發收集                器找不到足夠的空間,那么并發收集器將會停止,然后使用傳統的標記、清除方式進行回收。如果出現“碎片”,可                能需要進行如下配置:

    • -XX:+UseCMSCompactAtFullCollection:使用并發收集器時,開啟對年老代的壓縮。

    • -XX:CMSFullGCsBeforeCompaction=0:上面配置開啟的情況下,這里設置多少次Full GC后,對年老代進行壓縮


    一個性能較好的web服務器jvm參數配置:

    -server//服務器模式

-Xmx2g   //JVM最大允許分配的堆內存,按需分配
        -Xms2g   //JVM初始分配的堆內存,一般和Xmx配置成一樣以避免每次gc后JVM重新分配內存。
        -Xmn256m   //年輕代內存大小,整個JVM內存=年輕代 + 年老代 + 持久代
        -XX:PermSize=128m   //持久代內存大小
        -Xss256k   //設置每個線程的堆棧大小
        -XX:+DisableExplicitGC   //忽略手動調用GC, System.gc()的調用就會變成一個空調用,完全不觸發GC
        -XX:+UseConcMarkSweepGC  //并發標記清除(CMS)收集器
        -XX:+CMSParallelRemarkEnabled   //降低標記停頓
        -XX:+UseCMSCompactAtFullCollection   //在FULL GC的時候對年老代的壓縮
       -XX:LargePageSizeInBytes=128m   //內存頁的大小
        -XX:+UseFastAccessorMethods   //原始類型的快速優化
        -XX:+UseCMSInitiatingOccupancyOnly //使用手動定義初始化定義開始CMS收集
        -XX:CMSInitiatingOccupancyFraction=70 //使用cms作為垃圾回收使用70%后開始CMS收集



來自: http://my.oschina.net/manmao/blog/601933

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