JAVA性能優(yōu)化—IBM JDK JVM參數(shù)設置
www.firnow.com 時間 : 2010-06-09 作者:匿名 編輯:壹枝雪糕 點擊: 357 [ 評論 ]
-
-
綜合 資源 電子書 社區(qū) 在前一篇中,說了對WebSphere優(yōu)化的關鍵點——因不同JDK而異。本文將描述IBM JDK下常用參數(shù)的設置。
-Xms:最小堆大小
-Xmx:最大堆大小
-Xminf and -Xmaxf:GC(垃圾回收)之后可用空間的最小值最大值
-Xmine and -Xmaxe:堆增長的最小最大值
-Xmint and -Xmaxt:垃圾回收占時間整個運行時間的比例,默認是5%。如果回收時間小于5%,那么它就縮減堆,反之增大。
如果使用大小可變的堆(比如,-Xms 和 -Xmx 不同),應用程序可能遇到這樣的情況,不斷出現(xiàn)分配失敗而堆沒有擴展。這就是堆失效,是由于堆的大小剛剛能夠避免擴展但又不足以解決以后的分配失敗而造成的。通常,垃圾收集周期釋放的空間不僅可以滿足當前的分配失敗,而且還有很多可供以后的分配請求使用的空間。但是,如果堆處于失效狀態(tài),那么每個垃圾收集周期釋放的空間剛剛能夠滿足當前的分配失敗。結果,下一次分配請求時,又會進入垃圾收集周期,依此類推。大量生存時間很短的對象也可能造成這種現(xiàn)象。避免這種循環(huán)的一種辦法是增加 -Xminf 和 -Xmaxf 的值。比方說,如果使用 -Xminf.5,堆將增長到至少有 50% 的自由空間。同樣,增加 -Xmaxf 也是很合理。如果 -Xminf等于0.5,-Xmaxf 為默認值 0.6,因為 JVM 要把自由空間比例保持在 50% 和 60% 之間,所以就會出現(xiàn)太多的擴展和收縮。兩者相差 0.3 是一個不錯的選擇,這樣 -Xmaxf.8 可以很好地匹配 -Xminf.5。
如果記錄表明,需要多次擴展才能達到穩(wěn)定的堆大小,但可以更改 -Xmine,根據(jù)應用程序的行為來設置擴展大小的最小值。目標是獲得足夠的可用空間,不僅能滿足當前的請求,而且能滿足以后的很多請求,從而避免過多的垃圾收集周期。-Xmine、-Xmaxf 和 -Xminf 為控制應用程序的內存使用特性提供了很大的靈活性。
摘自Java性能優(yōu)化的策略和常見方法
所以在應用正式上線的頭一段時間,最好把GC日志打開,觀察一下堆(heap)的增長(expasion)和收縮(shrinkage)。最佳的情況就是,每次回收后可用的堆大小占整個堆的50%左右。如果回收后才騰出30%不到的可用空間,那就該再調整一下上述的參數(shù)了。下圖看起來直觀一點,使用-verbose:size參數(shù)可以查看當前的默認值。
那為何不把Xms和Xmx設置成一樣大,就像SUN的JDK所推薦的那樣?
Using the same values is not usually a good idea, because it delays the start of garbage collection until the heap is full. The first time that the Garbage Collector runs, therefore, becomes a very expensive operation. Also, the heap is more likely to be fragmented and require a heap compaction. Again this is a very expensive operation.
If the Garbage Collector cannot find enough garbage, it runs compaction. If the Garbage Collector finds enough garbage, or any of the other conditions for heap expansion are met , the Garbage Collector expands the heap.
因為IBM JDK采用的是標記(mark)-掃描(sweep)-標記-……-掃描-緊湊排列(compact),如果還不能提供足夠的空間,擴展堆(expasion)。依次循環(huán),直到達到最大堆大小。每次擴展前,那些長存的對象就被調整到堆的底部,每次擴展后需要再動的量就很少。所以如果把Xms設置成和Xmx一樣,那么掃描和緊湊排列這么一個充滿內存碎片的大堆的開銷將大大高于從小擴展堆的開銷。
The overheads of expanding the heap are almost trivial compared to the cost of collecting and compacting a very large fragmented heap.
這是由于IBM的GC特點造成的,而SUN的JDK采用的是分代回收的策略,所以就沒有這種情況,反而會受益于堆大小一致。不過這么說起來,用了-Xgcpolicy:gencon,就應該把最小堆最大堆設置成一樣咯。
在Gencon回收策略下,可以通過-Xmn來設置嬰兒區(qū)域(Nursery或者叫young)的大小,通過-Xmo來設置長存區(qū)(tenured或者old)的大小。注意-Xmn不能和-Xmns/-Xmnx參數(shù)一起使用,-Xmo不能和-Xmos/-Xmox一起使用,否則會報錯。前者就是把年輕代和長存代的大小固定了,而后兩者就是設定兩個部分最大最小的范圍,默認情況下:
-Xmns是-Xms的25%或者64M(在JDK 5.0中默認是25%)
-Xmnx是-Xmx的25%或者64M(同上)
-Xmos是-Xmx減去-Xmns的大小
-Xmox是和-Xmx一樣大
可見默認的年輕代太小了,生產環(huán)境中有必要改大一點。因為年輕代使用的是復制策略,所以回收速度相當快(minor gc),而長存代使用的是和optavgpause 策略相似的方式進行并發(fā)標志、掃描策略,回收速度比較慢(major gc)。理想情況是minor gc和major gc的比值在1:10左右。(可以通過GC日志查看回收的區(qū)域)
gencon中年老期限(Tenure age)和傾斜比率(Tilt ratio)這兩個參數(shù)是JVM自己動態(tài)調整的。
針對固定對象問題(Pinned Objects),使用-Xk -Xp參數(shù)設定kCluster和pCluster,Avoiding Java heap fragmentation with Java SDK V1.4.2.
一些不常用的參數(shù):
-Xloainitial -Xloamaximum :調整大對象區(qū)域(Large Object Area)的大小。分配總是先在SOA(Small Object Area)中分配,如果沒有空間并且需要分配的大小大于64K,那么分配到LOA。默認情況下為-Xloainitial0.05 (5%),-Xloamaximum0.5 (50%),如果你的程序確實需要分配許多大對象的話(大于64K),那么可以調整LOA的初始百分比。
總結一下來說,對于optthruput和optavgpause,設置恰當?shù)淖畲蠖押妥钚《?,設置-Xk和-Xp避免碎片問題,如果程序需要分配大對象較多,那么調整一下LOA的大?。粚τ趃encon,可以調大最小堆和最大堆接近,調整young區(qū)域的大小,LOA也可以視情況調整。subpool一般用不到,就不去研究了。
一些另外的信息
Default settings for the JVM
JVM environment settings
默認的Heapdumps是關閉的,調試的時候記得打開;默認的Javadumps on out of memory和Heapdumps on out of memory都是開啟的,但是默認的dump位置是profile的所在目錄,最好在管理控制臺java進程中把IBM_HEAPDUMPDIR和IBM_JAVACOREDIR設置到別的目錄,防止dump內容把WAS的文件系統(tǒng)撐爆,影響正常業(yè)務使用。
在Windows機器上,如果內存大于4G,記得開啟/3GB參數(shù),這樣可以使JVM Heap可以設置的更大一些,接近2G-1,(其它的三部分可以擴展到另外的1G上去),但一般最大不超過1.7G。