jvmjdk:JAVA性能优化—IBM JDK JVM参数设置

-Xms:最小堆大小

-Xmx:最大堆大小

-Xminf and -Xmaxf:GC(垃圾回收)的后可用空间最小值最大值

-Xmine and -Xmaxe:堆增长最小最大值

-Xm and -Xmaxt:垃圾回收占时间整个运行时间比例默认是5%如果回收时间小于5%那么它就缩减堆反的增大

般来说只要对Xms和Xmx设置合理后面 3对不用特别设置可以看看http://publib.boulder.ibm.com/infocenter/javasdk/v5r0/index.jsp上heap expasion和heap shrinkage两章介绍说明除非有下文情况:

如果使用大小可变堆(比如-Xms 和 -Xmx 区别)应用可能遇到这样情况不断出现分配失败而堆没有扩展这就是堆失效是由于堆大小刚刚能够避免扩展但又不足以解决以后分配失败而造成通常垃圾收集周期释放空间不仅可以满足当前分配失败而且还有很多可供以后分配请求使用空间但是如果堆处于失效状态那么每个垃圾收集周期释放空间刚刚能够满足当前分配失败结果次分配请求时又会进入垃圾收集周期依此类推大量生存时间很短对象也可能造成这种现象避免这种循环种办法是增加 -Xminf 和 -Xmaxf 比方说如果使用 -Xminf.5堆将增长到至少有 50% 自由空间同样增加 -Xmaxf 也是很合理如果 -Xminf等于0.5-Xmaxf 为默认值 0.6 JVM 要把自由空间比例保持在 50% 和 60% 的间所以就会出现太多扩展和收缩两者相差 0.3 是个不错选择这样 -Xmaxf.8 可以很好地匹配 -Xminf.5
如果记录表明需要多次扩展才能达到稳定堆大小但可以更改 -Xmine根据应用行为来设置扩展大小最小值目标是获得足够可用空间不仅能满足当前请求而且能满足以后很多请求从而避免过多垃圾收集周期-Xmine、-Xmaxf 和 -Xminf 为控制应用内存使用特性提供了很大灵活性

摘自Java性能优化策略和常见思路方法

所以在应用正式上线段时间最好把GC日志打开观察下堆(heap)增长(expasion)和收缩(shrinkage)最佳情况就是每次回收后可用堆大小占整个堆50%左右如果回收后才腾出30%不到可用空间那就该再调整下上述参数了下图看起来直观使用-verbose:size参数可以查看当前默认值



那为何不把Xms和Xmx设置成样大就像SUNJDK所推荐那样?

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)依次循环直到达到最大堆大小每次扩展前那些长存对象就被调整到堆底部每次扩展后需要再动量就很少所以如果把Xms设置成和Xmx那么扫描和紧凑排列这么个充满内存碎片大堆开销将大大高于从小扩展堆开销

The overheads of expanding the heap are almost trivial compared to the cost of collecting and compacting a very large fragmented heap.
这是由于IBMGC特点造成而SUNJDK采用是分代回收策略所以就没有这种情况反而会受益于堆大小不过这么说起来用了-Xgcpolicy:gencon就应该把最小堆最大堆设置成样咯

在Gencon回收策略下可以通过-Xmn来设置婴儿区域(Nursery或者叫young)大小通过-Xmo来设置长存区(tenured或者old)大小注意-Xmn不能和-Xmns/-Xmnx参数起使用-Xmo不能和-Xmos/-Xmox起使用否则会报错前者就是把年轻代和长存代大小固定了而后两者就是设定两个部分最大最小范围默认情况下:

-Xmns是-Xms25%或者64M(在JDK 5.0中默认是25%)

-Xmnx是-Xmx25%或者64M(同上)

-Xmos是-Xmx减去-Xmns大小

-Xmox是和-Xmx样大

可见默认年轻代太小了生产环境中有必要改大年轻代使用是复制策略所以回收速度相当快(minor gc)而长存代使用是和optavgpause 策略相似方式进行并发标志、扫描策略回收速度比较慢(major gc)理想情况是minor gc和major gc比值在1:10左右(可以通过GC日志查看回收区域)

gencon中年老期限(Tenure age)和倾斜比率(Tilt ratio)这两个参数是JVM自己动态调整

针对固定对象问题(Pinned Objects)使用-Xk -Xp参数设定kCluster和pClusterAvoiding Java heap fragmentation with Java SDK V1.4.2.

些不常用参数:

-Xloainitial<percentage> -Xloamaximum<percentage> :调整大对象区域(Large Object Area)大小分配总是先在SOA(Small Object Area)中分配如果没有空间并且需要分配大小大于64K那么分配到LOA默认情况下为-Xloainitial0.05 (5%)-Xloamaximum0.5 (50%)如果你确实需要分配许多大对象话(大于64K)那么可以调整LOA百分比

整理总结下来说对于optthruput和optavgpause设置恰当最大堆和最小堆设置-Xk和-Xp避免碎片问题如果需要分配大对象较多那么调整下LOA大小;对于gencon可以调大最小堆和最大堆接近调整young区域大小LOA也可以视情况调整subpool般用不到就不去研究了

些另外信息

Default tings for the JVM

http://publib.boulder.ibm.com/infocenter/javasdk/v5r0/index.jsp?topic=/com.ibm.java.doc.diagnostics.50/diag/appendixes/defaults.html

JVM environment tings

http://publib.boulder.ibm.com/infocenter/javasdk/v5r0/index.jsp?topic=/com.ibm.java.doc.diagnostics.50/diag/appendixes/env_var/env_jvm.html

默认Heapdumps是关闭调试时候记得打开;默认Javadumps on out of memory和Heapdumps on out of memory都是开启但是默认dump位置是profile所在目录最好在管理控制台java进程中把IBM_HEAPDUMPDIR和IBM_JAVACOREDIR设置到别目录防止dump内容把WAS文件系统撑爆影响正常业务使用

在Windows机器上如果内存大于4G记得开启/3GB参数这样可以使JVM Heap可以设置更大接近2G-1(其它 3部分可以扩展到另外1G上去)般最大不超过1.7G
Tags:  jdk优化 添加jvm参数 jvm参数 jvmjdk

延伸阅读

最新评论

发表评论