概述html
公司的江南白衣写了一篇关键业务系统的JVM参数推荐(2016热冬版)的文章,大牛的文章老是须要细细品读。这篇文章介绍大量的JVM调优参数,内容也比较多,本文只是列出我本身能理解的一些参数,暂时理解不了的参数就只能等之后本身实力到家了,再慢慢补充上来。java
性能调优参数算法
JAVA进程启动的时候,会加载rt.jar这个核心包的,rt.jar包里的Integer天然也是被加载到JVM中,Integer里面有一个IntegerCache缓存,以下:缓存
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
}
private IntegerCache() {}
}复制代码
IntegerCache有一个静态代码块,JVM在加载Integer这个类时,会优先加载静态的代码。当JVM进程启动完毕后, -128 ~ +127 范围的数字会被缓存起来,调用valueOf方法的时候,若是是这个范围内的数字,则直接从缓存取出。
超过这个范围的,就只能构造新的Integer对象了。bash
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}复制代码
所以能够根据实际状况把AutoBoxCacheMax的值设置的大写,好比江南白衣推荐的并发
-XX:AutoBoxCacheMax=20000复制代码
JAVA进程启动的时候,虽然咱们能够为JVM指定合适的内存大小,可是这些内存操做系统并无真正的分配给JVM,而是等JVM访问这些内存的时候,才真正分配,这样会形成如下问题。
一、GC的时候,新生代的对象要晋升到老年代的时候,须要内存,这个时候操做系统才真正分配内存,这样就会加大young gc的停顿时间;
二、可能存在内存碎片的问题。jvm
能够在JVM启动的时候,配置性能
-XX:+AlwaysPreTouch复制代码
参数,这样JVM就会先访问全部分配给它的内存,让操做系统把内存真正的分配给JVM.后续JVM就能够顺畅的访问内存了。学习
GC参数ui
JAVA 1.7用的垃圾收集算法仍是CMS,下文提到的参数都是针对CMS的。
以前写过一篇java垃圾回收算法之-CMS(并发标记清除),里面提到垃圾收集线程会跟应用的线程一块儿并行的工做,万一垃圾收集线程在工做的时候,老年代内存不足怎么办?所以最好仍是提早启动CMS来收集垃圾(CMS GC)。
能够经过设置
CMSInitiatingOccupancyFraction=75复制代码
那么当老年代堆空间的使用率达到75%的时候就开始执行垃圾回收,CMSInitiatingOccupancyFraction默认值是92%,这个就太大了。
CMSInitiatingOccupancyFraction参数必须跟下面两个参数一块儿使用才能生效的。
-XX:+UseConcMarkSweepGC
-XX:+UseCMSInitiatingOccupancyOnly复制代码
新生代是使用copy算法来进行垃圾回收的,能够参看
默认状况下,当新生代执行了15次young gc后,若是还有对象存活在Survivor区中,那么就能够直接将这些对象晋升到老年代,可是因为新生代使用copy算法,若是Survivor区存活的对象过久的话,Survivor区存活的对象就越多,这个就会影响copy算法的性能,使得young gc停顿的时间加长,建议设置成6。
-XX:MaxTenuringThreshold=6复制代码
若是系统使用堆外内存,好比用到了Netty的DirectByteBuffer类,那么当想回收堆外内存的时候,须要调用
System.gc()复制代码
而这个方法将进行full gc,整个应用将会停顿,若是是使用CMS垃圾收集器,那么能够设置
-XX:+ExplicitGCInvokesConcurrent复制代码
这个参数来改变System.gc()
的行为,让其从full gc --> CMS GC,CMS GC是并发收集的,且中间执行的过程当中,只有部分阶段须要stop the world。
注意:设置了ExplicitGCInvokesConcurrent,那就不要设置DisableExplicitGC参数来禁掉System.gc()
。
内存参数
这两个通常都是设置4个g
GC最多的仍是发生在新生代的young gc,因此能够提升一下新生代在整个堆的占用比例,建议设置为对半分,尽可能避免young gc
-XX:NewRatio=1复制代码
原文连接