走進JVM(二) JVM內存配置Xms/Xmx/PermSize/MaxPermSize

通過JVM的這些選項:Xms/Xmx/PermSize/MaxPermSize可以牽扯出很多問題,比如性能調優等。

說明:以下轉載沒經過實踐。

經驗實例(參考):

設置每個線程的堆棧大小。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內存管理的機制:

1、堆(Heap)和非堆(Non-heap)內存

按照官方的說法:“Java虛擬機具有一個堆,堆是運行時數據區域,所有類實例和數組的內存均從此處分配。堆是在Java虛擬機啟動時創建的。”,“在JVM中堆之外的內存稱為非堆內存(Non-heap memory)”。

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

1.1、堆內存分配

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.2、非堆內存分配

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的時候。 ?

2、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,因為有一部分被硬件占用了。

3、堆大小設置

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

3.1、典型設置:

3.1.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.2、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區進行多次復制,這樣可以增加對象再年輕代的存活時間,增加在年輕代即被回收的概論。

4、回收器選擇

JVM給了三種選擇:串行收集器、并行收集器、并發收集器,但是串行收集器只適用于小數據量的情況,所以這里的選擇主要針對并行收集器和并發收集器。默認情況下,JDK5.0以前都是使用串行收集器,如果想使用其他收集器需要在啟動時加入相應參數。JDK5.0以后,JVM會根據當前系統配置進行判斷。

4.1、吞吐量優先的并行收集器

如上文所述,并行收集器主要以到達一定的吞吐量為目標,適用于科學技術和后臺處理等。

4.1.1、典型配置

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

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

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

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

4.1.1.3、java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC??-XX:MaxGCPauseMillis=100

  • -XX:MaxGCPauseMillis=100:設置每次年輕代垃圾回收的最長時間,如果無法滿足此時間,JVM會自動調整年輕代大小,以滿足此值。

4.1.1.4、java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC? -XX:MaxGCPauseMillis=100?-XX:+UseAdaptiveSizePolicy

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

4.2、響應時間優先的并發收集器

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

4.2.1、典型配置

4.2.1.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.2、java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseConcMarkSweepGC?-XX:CMSFullGCsBeforeCompaction=5?-XX:+UseCMSCompactAtFullCollection

  • -XX:CMSFullGCsBeforeCompaction:由于并發收集器不對內存空間進行壓縮、整理,所以運行一段時間以后會產生“碎片”,使得運行效率降低。此值設置運行多少次GC以后對內存空間進行壓縮、整理。
  • -XX:+UseCMSCompactAtFullCollection:打開對年老代的壓縮。可能會影響性能,但是可以消除碎片

4.3、輔助信息

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

4.3.1、-XX:+PrintGC

輸出形式

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

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

4.3.2、-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.3、-XX:+PrintGCTimeStamps?-XX:+PrintGC:PrintGCTimeStamps可與上面兩個混合使用

輸出形式:

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

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

輸出形式:

Application time: 0.5291524 seconds

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

輸出形式:

Total time for which application threads were stopped: 0.0468229 seconds

4.3.6、-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.7、-Xloggc:filename:與上面幾個配合使用,把相關日志信息記錄到文件以便分析。

5、常見配置匯總

5.1、堆設置

  • -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.2、收集器設置

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

5.3、垃圾回收統計信息

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

5.4、并行收集器設置

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

5.5、并發收集器設置

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

6、調優總結

6.1、年輕代大小選擇

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

6.2、年老代大小選擇

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

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

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

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

6.3、較小堆引起的碎片問題

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

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

7、調優實例

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

7.1、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.2、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.3、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.4、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.5、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.6、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.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

?

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,786評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,656評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,697評論 0 379
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,098評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,855評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,254評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,322評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,473評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,014評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,833評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,016評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,568評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,273評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,680評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,946評論 1 288
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,730評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,006評論 2 374

推薦閱讀更多精彩內容

  • 1.一些概念 1.1.數據類型 Java虛擬機中,數據類型可以分為兩類:基本類型和引用類型。基本類型的變量保存原始...
    落落落落大大方方閱讀 4,556評論 4 86
  • jvm原理 Java虛擬機是整個java平臺的基石,是java技術實現硬件無關和操作系統無關的關鍵環節,是java...
    AI喬治閱讀 17,276評論 21 486
  • Java 虛擬機有自己完善的硬件架構, 如處理器、堆棧、寄存器等,還具有相應的指令系統。JVM 屏蔽了與具體操作系...
    尹小凱閱讀 1,702評論 0 10
  • 本文由作者自行翻譯,未經作者授權,不得隨意轉發。后續作者會陸續發布一系列關于JVM內存管理的文章,敬請期待。 1、...
    猿學堂閱讀 1,375評論 0 50
  • 這篇文章是我之前翻閱了不少的書籍以及從網絡上收集的一些資料的整理,因此不免有一些不準確的地方,同時不同JDK版本的...
    高廣超閱讀 15,656評論 3 83