Java JVM虛擬機選項Xms/Xmx/PermSize/MaxPermSize(轉)

經過JVM的這些選項:Xms/Xmx/PermSize/MaxPermSize能夠牽扯出不少問題,好比性能調優等。html

說明:如下轉載沒通過實踐。java

經驗實例(參考):web

設置每一個線程的堆棧大小。JDK5.0之後每一個線程堆棧大小爲1M,之前每一個線程堆棧大小爲256K。更具應用的線程所需內存大小進行調整。在相同物理內存下,減少這個值能生成更多的線程。可是操做系統對一個進程內的線程數仍是有限制的,不能無限生成,經驗值在3000~5000左右。算法

參數的含義:數組

  • -vmargs -Xms128M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M
  • -vmargs:說明後面是VM的參數,因此後面的其實都是JVM的參數了
  • -Xms128m:JVM初始分配的堆內存
  • -Xmx512m:JVM最大容許分配的堆內存,按需分配
  • -XX:PermSize=64M:JVM初始分配的非堆內存
  • -XX:MaxPermSize=128M:JVM最大容許分配的非堆內存,按需分配

VM內存管理的機制:緩存

一、堆(Heap)和非堆(Non-heap)內存服務器

按照官方的說法:「Java虛擬機具備一個堆,堆是運行時數據區域,全部類實例和數組的內存均今後處分配。堆是在Java虛擬機啓動時建立的。」,「在JVM中堆以外的內存稱爲非堆內存(Non-heap memory)」。併發

能夠看出JVM主要管理兩種類型的內存:堆和非堆。簡單來講堆就是Java代碼可及的內存,是留給開發人員使用的;非堆就是JVM留給本身用的,因此方法區、JVM內部處理或優化所需的內存(如JIT編譯後的代碼緩存)、每一個類結構(如運行時常數池、字段和方法數據)以及方法和構造方法的代碼都在非堆內存中。 app

1.一、堆內存分配eclipse

JVM初始分配的堆內存由-Xms指定,默認是物理內存的1/64;JVM最大分配的堆內存由-Xmx指定,默認是物理內存的1/4。默認空餘堆內存小於40%時,JVM就會增大堆直到-Xmx的最大限制;

空餘堆內存大於70%時,JVM會減小堆直到-Xms的最小限制。所以服務器通常設置-Xms、-Xmx 相等以免在每次GC 後調整堆的大小。

說明:若是-Xmx不指定或者指定偏小,應用可能會致使java.lang.OutOfMemory錯誤,此錯誤來自JVM,不是Throwable的,沒法用try...catch捕捉。 

1.二、非堆內存分配

JVM使用-XX:PermSize設置非堆內存初始值,默認是物理內存的1/64;由XX:MaxPermSize設置最大非堆內存的大小,默認是物理內存的1/4。(還有一說:MaxPermSize缺省值和-server -client選項相關,-server選項下默認MaxPermSize爲64m,-client選項下默認MaxPermSize爲32m。這個我沒有實驗。)

上面錯誤信息中的PermGen space的全稱是Permanent Generation space,是指內存的永久保存區域。尚未弄明白PermGen space是屬於非堆內存,仍是就是非堆內存,但至少是屬於了。

XX:MaxPermSize設置太小會致使java.lang.OutOfMemoryError: PermGen space 就是內存益出。 

說說爲何會內存益出: 

  1. 這一部份內存用於存放Class和Meta的信息,Class在被 Load的時候被放入PermGen space區域,它和存放Instance的Heap區域不一樣。 
  2. GC(Garbage Collection)不會在主程序運行期對PermGen space進行清理,因此若是你的APP會LOAD不少CLASS 的話,就極可能出現PermGen space錯誤。這種錯誤常見在web服務器對JSP進行pre compile的時候。  

二、JVM內存限制(最大值)

首先JVM內存限制於實際的最大物理內存,假設物理內存無限大的話,JVM內存的最大值跟操做系統有很大的關係。簡單的說就32位處理器雖然可控內存空間有4GB,可是具體的操做系統會給一個限制,這個限制通常是2GB-3GB(通常來講Windows系統下爲1.5G-2G,Linux系統下爲2G-3G),而64bit以上的處理器就不會有限制了。

爲何有的機器我將-Xmx和-XX:MaxPermSize都設置爲512M以後Eclipse能夠啓動,而有些機器沒法啓動?

經過上面對JVM內存管理的介紹咱們已經瞭解到JVM內存包含兩種:堆內存和非堆內存,另外JVM最大內存首先取決於實際的物理內存和操做系統。因此說設置VM參數致使程序沒法啓動主要有如下幾種緣由:

  1. 參數中-Xms的值大於-Xmx,或者-XX:PermSize的值大於-XX:MaxPermSize;
  2. -Xmx的值和-XX:MaxPermSize的總和超過了JVM內存的最大限制,好比當前操做系統最大內存限制,或者實際的物理內存等等。說到實際物理內存這裏須要說明一點的是,若是你的內存是1024MB,但實際系統中用到的並不多是1024MB,由於有一部分被硬件佔用了。

三、堆大小設置

JVM 中最大堆大小有三方面限制:相關操做系統的數據模型(32-bt仍是64-bit)限制;系統的可用虛擬內存限制;系統的可用物理內存限制。32位系統下,通常限制在1.5G~2G;64爲操做系統對內存無限制。我在Windows Server 2003系統,3.5G物理內存,JDK5.0下測試,最大可設置爲1478m。

3.一、典型設置:

3.1.一、java -Xmx3550m -Xms3550m -Xmn2g-Xss128k

  • -Xmx3550m:設置JVM最大可用內存爲3550M。
  • -Xms3550m:設置JVM促使內存爲3550m。此值能夠設置與-Xmx相同,以免每次垃圾回收完成後JVM從新分配內存。
  • -Xmn2g:設置年輕代大小爲2G。整個JVM內存大小=年輕代大小 + 年老代大小 + 持久代大小。持久代通常固定大小爲64m,因此增大年輕代後,將會減少年老代大小。此值對系統性能影響較大,Sun官方推薦配置爲整個堆的3/8。
  • -Xss128k:設置每一個線程的堆棧大小。JDK5.0之後每一個線程堆棧大小爲1M,之前每一個線程堆棧大小爲256K。更具應用的線程所需內存大小進行調整。在相同物理內存下,減少這個值能生成更多的線程。可是操做系統對一個進程內的線程數仍是有限制的,不能無限生成,經驗值在3000~5000左右。

3.1.二、java -Xmx3550m -Xms3550m -Xss128k -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MaxPermSize=16m -XX:MaxTenuringThreshold=0

  • -XX:NewRatio=4:設置年輕代(包括Eden和兩個Survivor區)與年老代的比值(除去持久代)。設置爲4,則年輕代與年老代所佔比值爲1:4,年輕代佔整個堆棧的1/5
  • -XX:SurvivorRatio=4:設置年輕代中Eden區與Survivor區的大小比值。設置爲4,則兩個Survivor區與一個Eden區的比值爲2:4,一個Survivor區佔整個年輕代的1/6
  • -XX:MaxPermSize=16m:設置持久代大小爲16m。
  • -XX:MaxTenuringThreshold=0:設置垃圾最大年齡。若是設置爲0的話,則年輕代對象不通過Survivor區,直接進入年老代。對於年老代比較多的應用,能夠提升效率。若是將此值設置爲一個較大值,則年輕代對象會在Survivor區進行屢次複製,這樣能夠增長對象再年輕代的存活時間,增長在年輕代即被回收的概論。

四、回收器選擇

JVM給了三種選擇:串行收集器、並行收集器、併發收集器,可是串行收集器只適用於小數據量的狀況,因此這裏的選擇主要針對並行收集器和併發收集器。默認狀況下,JDK5.0之前都是使用串行收集器,若是想使用其餘收集器須要在啓動時加入相應參數。JDK5.0之後,JVM會根據當前系統配置進行判斷。

4.一、吞吐量優先的並行收集器

如上文所述,並行收集器主要以到達必定的吞吐量爲目標,適用於科學技術和後臺處理等。

4.1.一、典型配置

4.1.1.一、java -Xmx3800m -Xms3800m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20

  • -XX:+UseParallelGC:選擇垃圾收集器爲並行收集器。此配置僅對年輕代有效。即上述配置下,年輕代使用併發收集,而年老代仍舊使用串行收集。
  • -XX:ParallelGCThreads=20:配置並行收集器的線程數,即:同時多少個線程一塊兒進行垃圾回收。此值最好配置與處理器數目相等。

4.1.1.二、java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:+UseParallelOldGC

  • -XX:+UseParallelOldGC:配置年老代垃圾收集方式爲並行收集。JDK6.0支持對年老代並行收集。

4.1.1.三、java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC  -XX:MaxGCPauseMillis=100

  • -XX:MaxGCPauseMillis=100:設置每次年輕代垃圾回收的最長時間,若是沒法知足此時間,JVM會自動調全年輕代大小,以知足此值。

4.1.1.四、java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC  -XX:MaxGCPauseMillis=100 -XX:+UseAdaptiveSizePolicy

  • -XX:+UseAdaptiveSizePolicy:設置此選項後,並行收集器會自動選擇年輕代區大小和相應的Survivor區比例,以達到目標系統規定的最低相應時間或者收集頻率等,此值建議使用並行收集器時,一直打開。

4.二、響應時間優先的併發收集器

如上文所述,併發收集器主要是保證系統的響應時間,減小垃圾收集時的停頓時間。適用於應用服務器、電信領域等。

4.2.一、典型配置

4.2.1.一、java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:ParallelGCThreads=20 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC

  • -XX:+UseConcMarkSweepGC:設置年老代爲併發收集。測試中配置這個之後,-XX:NewRatio=4的配置失效了,緣由不明。因此,此時年輕代大小最好用-Xmn設置。
  • -XX:+UseParNewGC:設置年輕代爲並行收集。可與CMS收集同時使用。JDK5.0以上,JVM會根據系統配置自行設置,因此無需再設置此值。

4.2.1.二、java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseConcMarkSweepGC -XX:CMSFullGCsBeforeCompaction=5 -XX:+UseCMSCompactAtFullCollection

  • -XX:CMSFullGCsBeforeCompaction:因爲併發收集器不對內存空間進行壓縮、整理,因此運行一段時間之後會產生「碎片」,使得運行效率下降。此值設置運行多少次GC之後對內存空間進行壓縮、整理。
  • -XX:+UseCMSCompactAtFullCollection:打開對年老代的壓縮。可能會影響性能,可是能夠消除碎片

4.三、輔助信息

JVM提供了大量命令行參數,打印信息,供調試使用。主要有如下一些:

4.3.一、-XX:+PrintGC

輸出形式

[GC 118250K->113543K(130112K), 0.0094143 secs]

[Full GC 121376K->10414K(130112K), 0.0650971 secs]

4.3.二、-XX:+PrintGCDetails

輸出形式

[GC [DefNew: 8614K->781K(9088K), 0.0123035 secs] 118250K->113543K(130112K), 0.0124633 secs]

[GC [DefNew: 8614K->8614K(9088K), 0.0000665 secs][Tenured: 112761K->10414K(121024K), 0.0433488 secs] 121376K->10414K(130112K), 0.0436268 secs]

4.3.三、-XX:+PrintGCTimeStamps -XX:+PrintGC:PrintGCTimeStamps可與上面兩個混合使用

輸出形式:

11.851: [GC 98328K->93620K(130112K), 0.0082960 secs]

4.3.四、-XX:+PrintGCApplicationConcurrentTime:打印每次垃圾回收前,程序未中斷的執行時間。可與上面混合使用

輸出形式:

Application time: 0.5291524 seconds

4.3.五、-XX:+PrintGCApplicationStoppedTime:打印垃圾回收期間程序暫停的時間。可與上面混合使用

輸出形式:

Total time for which application threads were stopped: 0.0468229 seconds

4.3.六、-XX:PrintHeapAtGC:打印GC先後的詳細堆棧信息

輸出形式:

34.702: [GC {Heap before gc invocations=7:
 def new generation   total 55296K, used 52568K [0x1ebd0000, 0x227d0000, 0x227d0000)
eden space 49152K,  99% used [0x1ebd0000, 0x21bce430, 0x21bd0000)
from space 6144K,  55% used [0x221d0000, 0x22527e10, 0x227d0000)
  to   space 6144K,   0% used [0x21bd0000, 0x21bd0000, 0x221d0000)
 tenured generation   total 69632K, used 2696K [0x227d0000, 0x26bd0000, 0x26bd0000)
the space 69632K,   3% used [0x227d0000, 0x22a720f8, 0x22a72200, 0x26bd0000)
 compacting perm gen  total 8192K, used 2898K [0x26bd0000, 0x273d0000, 0x2abd0000)
   the space 8192K,  35% used [0x26bd0000, 0x26ea4ba8, 0x26ea4c00, 0x273d0000)
    ro space 8192K,  66% used [0x2abd0000, 0x2b12bcc0, 0x2b12be00, 0x2b3d0000)
    rw space 12288K,  46% used [0x2b3d0000, 0x2b972060, 0x2b972200, 0x2bfd0000)
34.735: [DefNew: 52568K->3433K(55296K), 0.0072126 secs] 55264K->6615K(124928K)Heap after gc invocations=8:
 def new generation   total 55296K, used 3433K [0x1ebd0000, 0x227d0000, 0x227d0000)
eden space 49152K,   0% used [0x1ebd0000, 0x1ebd0000, 0x21bd0000)
  from space 6144K,  55% used [0x21bd0000, 0x21f2a5e8, 0x221d0000)
  to   space 6144K,   0% used [0x221d0000, 0x221d0000, 0x227d0000)
 tenured generation   total 69632K, used 3182K [0x227d0000, 0x26bd0000, 0x26bd0000)
the space 69632K,   4% used [0x227d0000, 0x22aeb958, 0x22aeba00, 0x26bd0000)
 compacting perm gen  total 8192K, used 2898K [0x26bd0000, 0x273d0000, 0x2abd0000)
   the space 8192K,  35% used [0x26bd0000, 0x26ea4ba8, 0x26ea4c00, 0x273d0000)
    ro space 8192K,  66% used [0x2abd0000, 0x2b12bcc0, 0x2b12be00, 0x2b3d0000)
    rw space 12288K,  46% used [0x2b3d0000, 0x2b972060, 0x2b972200, 0x2bfd0000)
}
, 0.0757599 secs]

4.3.七、-Xloggc:filename:與上面幾個配合使用,把相關日誌信息記錄到文件以便分析。

五、常見配置彙總

5.一、堆設置

  • -Xms:初始堆大小
  • -Xmx:最大堆大小
  • -XX:NewSize=n:設置年輕代大小
  • -XX:NewRatio=n:設置年輕代和年老代的比值。如:爲3,表示年輕代與年老代比值爲1:3,年輕代佔整個年輕代年老代和的1/4
  • -XX:SurvivorRatio=n:年輕代中Eden區與兩個Survivor區的比值。注意Survivor區有兩個。如:3,表示Eden:Survivor=3:2,一個Survivor區佔整個年輕代的1/5
  • -XX:MaxPermSize=n:設置持久代大小

5.二、收集器設置

  • -XX:+UseSerialGC:設置串行收集器
  • -XX:+UseParallelGC:設置並行收集器
  • -XX:+UseParalledlOldGC:設置並行年老代收集器
  • -XX:+UseConcMarkSweepGC:設置併發收集器

5.三、垃圾回收統計信息

  • -XX:+PrintGC
  • -XX:+PrintGCDetails
  • -XX:+PrintGCTimeStamps
  • -Xloggc:filename

5.四、並行收集器設置

  • -XX:ParallelGCThreads=n:設置並行收集器收集時使用的CPU數。並行收集線程數。
  • -XX:MaxGCPauseMillis=n:設置並行收集最大暫停時間
  • -XX:GCTimeRatio=n:設置垃圾回收時間佔程序運行時間的百分比。公式爲1/(1+n)

5.五、併發收集器設置

  • -XX:+CMSIncrementalMode:設置爲增量模式。適用於單CPU狀況。
  • -XX:ParallelGCThreads=n:設置併發收集器年輕代收集方式爲並行收集時,使用的CPU數。並行收集線程數。

六、調優總結

6.一、年輕代大小選擇

  • 響應時間優先的應用儘量設大,直到接近系統的最低響應時間限制(根據實際狀況選擇)。在此種狀況下,年輕代收集發生的頻率也是最小的。同時,減小到達年老代的對象。
  • 吞吐量優先的應用:儘量的設置大,可能到達Gbit的程度。由於對響應時間沒有要求,垃圾收集能夠並行進行,通常適合8CPU以上的應用。

6.二、年老代大小選擇

6.2.一、響應時間優先的應用:年老代使用併發收集器,因此其大小須要當心設置,通常要考慮併發會話率會話持續時間等一些參數。若是堆設置小了,能夠會形成內存碎片、高回收頻率以及應用暫停而使用傳統的標記清除方式;若是堆大了,則須要較長的收集時間。最優化的方案,通常須要參考如下數據得到:

  • 併發垃圾收集信息
  • 持久代併發收集次數
  • 傳統GC信息
  • 花在年輕代和年老代回收上的時間比例

減小年輕代和年老代花費的時間,通常會提升應用的效率。

6.2.二、吞吐量優先的應用:通常吞吐量優先的應用都有一個很大的年輕代和一個較小的年老代。緣由是,這樣能夠儘量回收掉大部分短時間對象,減小中期的對象,而年老代盡存放長期存活對象。

6.三、較小堆引發的碎片問題

由於年老代的併發收集器使用標記、清除算法,因此不會對堆進行壓縮。當收集器回收時,他會把相鄰的空間進行合併,這樣能夠分配給較大的對象。可是,當堆空間較小時,運行一段時間之後,就會出現「碎片」,若是併發收集器找不到足夠的空間,那麼併發收集器將會中止,而後使用傳統的標記、清除方式進行回收。若是出現「碎片」,可能須要進行以下配置:

  • -XX:+UseCMSCompactAtFullCollection:使用併發收集器時,開啓對年老代的壓縮。
  • -XX:CMSFullGCsBeforeCompaction=0:上面配置開啓的狀況下,這裏設置多少次Full GC後,對年老代進行壓縮

七、調優實例

環境LinuxAS4,resin2.1.17,JDK6.0,2CPU,4G內存,dell2950服務器。

7.一、JVM調優之串行垃圾回收

也就是默認配置,完成10萬request用時153秒。JVM參數配置以下: 

$JAVA_ARGS.="-Dresin.home=$SERVER_ROOT-server  
-Xms2048M-Xmx2048M-Xmn512M
-XX:PermSize=256M-XX:MaxPermSize=256M 
-XX:MaxTenuringThreshold=7-XX:GCTimeRatio=19 
-Xnoclassgc-Xloggc:log/gc.log
-XX:+PrintGCDetails-XX:+PrintGCTimeStamps";  

這種配置通常在resin啓動24小時內彷佛沒有大問題,網站能夠正常訪問,但查看日誌發現,在接近24小時時,FullGC執行愈來愈頻繁,大約每隔3分鐘就有一次FullGC,每次FullGC系統會停頓6秒左右,做爲一個網站來講,用戶等待6秒恐怕太長了,因此這種方式有待改善。MaxTenuringThreshold=7表示一個對象若是在救助空間移動7次尚未被回收就放入年老代,GCTimeRatio=19表示java能夠用5%的時間來作垃圾回收,1/(1+19)=1/20=5%。

7.二、JVM調優之並行回收

完成10萬request用時117秒,配置以下: 

$JAVA_ARGS.="-Dresin.home=$SERVER_ROOT-server-Xmx2048M  
-Xms2048M-Xmn512M-XX:PermSize=256M-XX:MaxPermSize=256M 
-Xnoclassgc-Xloggc:log/gc.log-XX:+PrintGCDetails  
-XX:+PrintGCTimeStamps-XX:+UseParallelGC-XX:ParallelGCThreads=20 
-XX:+UseParallelOldGC-XX:MaxGCPauseMillis=500 
-XX:+UseAdaptiveSizePolicy-XX:MaxTenuringThreshold=7 
-XX:GCTimeRatio=19";  

並行回收我嘗試過多種組合配置,彷佛都沒什麼用,resin啓動3小時左右就會停頓,時間超過10秒。也有多是參數設置不夠好的緣由,MaxGCPauseMillis表示GC最大停頓時間,在resin剛啓動尚未執行FullGC時系統是正常的,但一旦執行FullGC,MaxGCPauseMillis根本沒有用,停頓時間可能超過20秒,以後會發生什麼我也再也不關心了,趕忙重啓resin,嘗試其餘回收策略。

7.三、JVM調優之併發回收

完成10萬request用時60秒,比並行回收差很少快一倍,是默認回收策略性能的2.5倍,配置以下: 

$JAVA_ARGS.="-Dresin.home=$SERVER_ROOT-server  
-Xms2048M-Xmx2048M-Xmn512M-XX:PermSize=256M 
-XX:MaxPermSize=256M-XX:+UseConcMarkSweepGC  
-XX:MaxTenuringThreshold=7-XX:GCTimeRatio=19 
-Xnoclassgc-Xloggc:log/gc.log-XX:+PrintGCDetails  
-XX:+PrintGCTimeStamps-XX:+UseCMSCompactAtFullCollection  
-XX:CMSFullGCsBeforeCompaction=0"; 

這個配置雖然不會出現10秒連不上的狀況,但系統重啓3個小時左右,每隔幾分鐘就會有5秒連不上的狀況,查看gc.log,發如今執行ParNewGC時有個promotionfailed錯誤,從而轉向執行FullGC,形成系統停頓,並且會很頻繁,每隔幾分鐘就有一次,因此還得改善。UseCMSCompactAtFullCollection是表是執行FullGC後對內存進行整理壓縮,省得產生內存碎片,CMSFullGCsBeforeCompaction=N表示執行N次FullGC後執行內存壓縮。

7.四、JVM調優之增量回收

完成10萬request用時171秒,太慢了,配置以下: 

$JAVA_ARGS.="-Dresin.home=$SERVER_ROOT-server  
-Xms2048M-Xmx2048M-Xmn512M-XX:PermSize=256M 
-XX:MaxPermSize=256M-XX:MaxTenuringThreshold=7 
-XX:GCTimeRatio=19-Xnoclassgc-Xloggc:log/gc.log  
-XX:+PrintGCDetails-XX:+PrintGCTimeStamps-Xincgc"; 

彷佛回收得也不太乾淨,並且也對性能有較大影響,不值得試。

7.五、JVM調優之併發回收的I-CMS模式

和增量回收差很少,完成10萬request用時170秒。配置以下: 

$JAVA_ARGS.="-Dresin.home=$SERVER_ROOT-server  
-Xms2048M-Xmx2048M-Xmn512M-XX:PermSize=256M 
-XX:MaxPermSize=256M-XX:MaxTenuringThreshold=7 
-XX:GCTimeRatio=19-Xnoclassgc-Xloggc:log/gc.log  
-XX:+PrintGCDetails-XX:+PrintGCTimeStamps  
-XX:+UseConcMarkSweepGC-XX:+CMSIncrementalMode  
-XX:+CMSIncrementalPacing  
-XX:CMSIncrementalDutyCycleMin=0 
-XX:CMSIncrementalDutyCycle=10-XX:-TraceClassUnloading"; 

採用了sun推薦的參數,回收效果很差,照樣有停頓,數小時以內就會頻繁出現停頓,什麼sun推薦的參數,照樣很差使。

7.六、JVM調優之遞增式低暫停收集器

又叫什麼火車式回收,完成10萬request用時153秒,配置以下: 

$JAVA_ARGS.="-Dresin.home=$SERVER_ROOT-server  
-Xms2048M-Xmx2048M-Xmn512M-XX:PermSize=256M 
-XX:MaxPermSize=256M-XX:MaxTenuringThreshold=7 
-XX:GCTimeRatio=19-Xnoclassgc-Xloggc:log/gc.log  
-XX:+PrintGCDetails-XX:+PrintGCTimeStamps-XX:+UseTrainGC"; 

該配置效果也很差,影響性能,因此沒試。

7.七、相比之下,仍是併發回收比較好,性能比較高,只要能解決ParNewGC(並行回收年輕代)時的promotionfailed錯誤就一切好辦了,查了不少文章,發現引發promotionfailed錯誤的緣由是CMS來不及回收(CMS默認在年老代佔到90%左右纔會執行),年老代又沒有足夠的空間供GC把一些活的對象從年輕代移到年老代,因此執行FullGC。CMSInitiatingOccupancyFraction=70表示年老代佔到約70%時就開始執行CMS,這樣就不會出現FullGC了。SoftRefLRUPolicyMSPerMB這個參數也是我認爲比較有用的,我以爲不必等1秒,因此設置成0。配置以下

$JAVA_ARGS.="-Dresin.home=$SERVER_ROOT-server-Xms2048M  
-Xmx2048M-Xmn512M-XX:PermSize=256M-XX:MaxPermSize=256M 
-XX:SurvivorRatio=8-XX:MaxTenuringThreshold=7 
-XX:GCTimeRatio=19-Xnoclassgc-XX:+DisableExplicitGC  
-XX:+UseParNewGC-XX:+UseConcMarkSweepGC  
-XX:+CMSPermGenSweepingEnabled  
-XX:+UseCMSCompactAtFullCollection  
-XX:CMSFullGCsBeforeCompaction=0 
-XX:+CMSClassUnloadingEnabled-XX:-CMSParallelRemarkEnabled  
-XX:CMSInitiatingOccupancyFraction=70 
-XX:SoftRefLRUPolicyMSPerMB=0-XX:+PrintClassHistogram  
-XX:+PrintGCDetails-XX:+PrintGCTimeStamps  
-XX:+PrintGCApplicationConcurrentTime  
-XX:+PrintGCApplicationStoppedTime  
-Xloggc:log/gc.log"; 

上面這個配置內存上升的很慢,24小時以內幾乎沒有停頓現象,最長的只停滯了0.8s,ParNewGC每30秒左右才執行一次,每次回收約0.2秒,看來問題應該暫時解決了。

參數不明白的能夠上網查,本人認爲比較重要的幾個參數是:

-Xms-Xmx-XmnMaxTenuringThresholdGCTimeRatioUse
ConcMarkSweepGCCMSInitiatingOccupancyFractionSoftRefLRUPolicyMSPerMB
eclipse中配置JVM參數:-Xmx1024M-Xms1000M-server-XX:PermSize=64M-XX:MaxPermSize=128m

 

參考:

http://technique-digest.iteye.com/blog/1123046(以上內容部分轉自此篇文章)

http://www.360doc.com/content/15/0330/12/16782314_459269672.shtml(以上部份內容轉自此篇文章)

http://www.51testing.com/html/80/n-862780.html(JVM的參數調優,解決GC回收時卡頓的問題)

http://www.importnew.com/15934.html(爲何JVM指定-Xmx參數後佔用內存會變少?)

http://www.cnblogs.com/chengxin1982/p/3818448.html

http://unixboy.iteye.com/blog/174173(以上內容部分轉自此篇文章)

http://www.cnblogs.com/koik/p/4452029.html

http://cxh61207.iteye.com/blog/1160663

http://blog.chinaunix.net/uid-26602509-id-4110150.html(Tomcat內存調優)

http://blog.csdn.net/zhushuai1221/article/details/51027024

http://developer.51cto.com/art/201201/312639.htm(調優專題頻道)

http://developer.51cto.com/art/201009/227848_all.htm(JVM調優實例,以上部份內容轉自此篇文章)

http://www.cnblogs.com/zhguang/p/Java-JVM-GC.html

http://uule.iteye.com/blog/2114697

http://blog.sina.com.cn/s/blog_3f12afd00100zpvf.html

http://yjph83.iteye.com/blog/2108105

相關文章
相關標籤/搜索